Python中的换行符与.rstrip()的问题
我正在做一个Python练习,要求我写一个程序,随机生成一个密码,密码需要满足以下条件:
密码由两个随机选择的单词组成,这些单词来自一个很大的文本文件,每行一个单词。
每个单词必须至少有3个字母,密码的总长度必须是8、9或10个字母。
这两个单词要连在一起(中间没有空格),而且每个单词的首字母要大写。
我的代码如下:
# Randomly generate a two-word password from a text file of words, subject to various conditions
from sys import exit
from random import choice
print()
try:
inf=open("words.txt","r")
except FileNotFoundError:
print("Error: words.txt not found.")
print("Quitting...")
exit()
words=inf.readlines()
for word in words:
word=word.rstrip()
word=word.lower()
first=choice(words)
words.remove(first)
second=choice(words)
while len(first)<=2 or len(second)<=2 or len(first)+len(second) not in [8,9,10]:
first=choice(words)
words.remove(first)
second=choice(words)
first=first[0].upper()+first[1:]
second=second[0].upper()+second[1:]
password=first+second
print(password)
在尝试这个练习时,我发现密码中的每个单词似乎在末尾都有一个多余的空格,这个空格其实是换行符 \n
。不过,我已经加了这一行 word=word.rstrip()
,我听说这应该能去掉所有的空格、制表符和换行符。但是,变量 first
和 second
仍然在末尾有 '\n',尽管它们是从列表 words
中随机选择的,并且已经应用了 .rstrip()。这是怎么回事呢?我肯定是漏掉了什么。
2 个回答
1
处理一个没有多余空格的文本文件,最简单的方法之一就是用 map() 函数。
为了满足输出的要求,你可以使用一个循环,这个循环理论上可以一直运行下去,具体取决于文件的内容。
不过,更好的方法是建立一个字典,字典的键是单词的长度,而每个键对应的值是一个包含该长度单词的列表。这样就不需要再用内层循环了,这样做更可靠,而且几乎肯定会更快。
from random import randint, choice
from collections import defaultdict
WORDSFILE = "words.txt"
db = defaultdict(list)
with open(WORDSFILE) as words:
# load the dictionary with words of length 3 to 7
for word in map(str.rstrip, words):
lw = len(word)
if 3 <= lw <= 7:
db[lw].append(word)
for k, v in db.items():
db[k] = list(set(v))
if len(db[k]) < 2:
raise Exception("There must be at least 2 unique words of each length")
# choose the total length
full_length = randint(8, 10)
# choose a length for the first word
first_len = randint(3, full_length-3)
# calculate length of second word
second_len = full_length - first_len
# random choice of the first word
first_word = choice(db[first_len])
# ensure that the chosen word cannot be duplicated
if first_len == second_len:
db[first_len].remove(first_word)
# random choice of the second word
second_word = choice(db[second_len])
password = first_word.capitalize() + second_word.capitalize()
print(password)
2
words=inf.readlines()
for word in words:
word=word.rstrip()
word=word.lower()
问题在于你在循环中修改了变量 word
,但没有修改列表 words
。我认为一个简单的解决办法是使用列表推导式。你可以这样写:words = [word.rstrip().lower() for word in words]
。这样,你的新列表就会去掉多余的空格,并且所有字母都变成小写。