我正在尝试创建一个程序,找到包含所需字母x的一定长度或更长的所有单词,并且单词中的其余字母是从y中的字母中提取的(这是在NYT中找到的拼图)。
由于我正在尝试逐步完成此操作,因此我首先创建一个长度为> =所需长度的所有单词的单词列表,然后创建包含所需字母的所有单词的列表。
然后,我浏览该列表中每个单词中的每个字母,看它们是否包含不在输入字母中的字母,或者使用该字母的次数多于输入中的字母。如果发生这种情况,我会从列表中删除该单词。
最后,我打印满足条件的所有单词。但是,它不起作用,我不知道为什么。我确定我在这里犯了一个真正的菜鸟错误,但我会喜欢任何建议。非常感谢,请原谅我可怕的代码,我只学习Python两周了!
data = [line.strip() for line in open("wordsEn.txt", 'r')]
req = str(input("Please enter the required letter "))
set = str(input("Please enter the other letters "))
completeset = req + set
lenreq = int(input("Please enter minimum word length "))
panswers = []
usedict = [word for word in data if len(word) >= lenreq]
for word in usedict:
if req in word:
panswers = panswers + [word]
panswerstest = panswers
for word in panswerstest:
for w in word:
if word.count(w) > completeset.count(w):
try:
panswers.remove(word)
except:
continue
print(panswers)
答案 0 :(得分:1)
由于您显然对Python很陌生,所以这里有一些关于您的代码的提示(这是Code Review比Stack Overflow更多,但是很好):
不要将整个单词列表作为列表加载到第一行;这非常耗费内存,会降低程序速度。一个常见的结构是
with open('myfile.txt') as f:
for line in f:
do_stuff_with(line)
for line in f
循环一次只加载一行,因此一次只能存储一行内存。这样效率更高。
更一般地说,您要创建几个大型列表:data
,panswers
和panswerstest
。当我尝试你的代码时,它因为列表太大而窒息。 (当我开始写这个答案时,我开始运行它;它还没有完成。)
如果你一次检查一个单词,它是否匹配,打印到stdout,然后直接进入下一行会更好。
不要将set
用于变量名称。 set
是built-in function,并且压倒这些是不好的做法(因为你会以意想不到的方式导致事情中断)。
分隔用于过滤单词列表的代码和用于获取用户输入的代码。我至少有两个功能:get_user_input()
和check_word_match(word)
。这使得您的代码可以重复使用,并且您可以从用于匹配单词的代码中解开用于输入用户输入的代码(例如,将长度转换为整数)。
使用更长的变量名称。字符很便宜,它使您更容易阅读代码。 (例如lenreq
〜> required_length
,panswers ~> possible_answers
)
不清楚匹配是否区分大小写(如果是,则应该向用户说明)。如果需要,在代码中填充lower()
将有助于使其不区分大小写。
在Python 3中,input()
会返回一个字符串,因此无需使用str()
重新生成字符串。
使用裸except:
总是一个坏主意,因为你可以捕捉到你不想要的错误(这会捕获所有错误)。最好抓住你知道会引发的特定异常。
在这种情况下,我猜你正在抛出一个ValueError,因为你试图删除一个不在列表中的项目,所以你应该使用except ValueError:
。 (虽然我不确定如何;一旦panswerstest
是panswers
的副本,我就不确定如何发生这种情况。)
所以这就是我重写代码的方式:
def get_user_input():
user_input = {}
user_input['required'] = input('Please enter the required letter ')
user_input['additional'] = input('Please enter the other letters ')
user_input['minimum_length'] = int(input('Please enter the minimum word length '))
return user_input
def match_word(word, required, additional, minimum_length):
'''
Returns True if a word matches the following criteria:
1) It is at least minimum_length
1) It contains the required characters
2) It only contains letters from (required + additional)
'''
if len(word) < minimum_length:
return False
if required not in word:
return False
complete_char_set = required + additional
for char in word:
if word.count(char) > complete_char_set.count(char):
return False
return True
user_input = get_user_input()
# /usr/share/dict/words is a list of English words found on many Unix
# systems; swap it out for any text file containing a list of words.
with open('/usr/share/dict/words') as f:
for line in f:
word = line.strip()
if match_word(word,
required=user_input['required'],
additional=user_input['additional'],
minimum_length=user_input['minimum_length']):
print(word)
我已将代码分成两个函数并删除了所有大型列表。该版本运行得更快(几秒钟),因为没有任何大型循环需要担心。