Python中的换行符与.rstrip()的问题

-1 投票
2 回答
45 浏览
提问于 2025-04-12 10:22

我正在做一个Python练习,要求我写一个程序,随机生成一个密码,密码需要满足以下条件:

  1. 密码由两个随机选择的单词组成,这些单词来自一个很大的文本文件,每行一个单词。

  2. 每个单词必须至少有3个字母,密码的总长度必须是8、9或10个字母。

  3. 这两个单词要连在一起(中间没有空格),而且每个单词的首字母要大写。

我的代码如下:

# 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(),我听说这应该能去掉所有的空格、制表符和换行符。但是,变量 firstsecond 仍然在末尾有 '\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]。这样,你的新列表就会去掉多余的空格,并且所有字母都变成小写。

撰写回答