首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解决字谜?

解决字谜?
EN

Stack Overflow用户
提问于 2015-06-17 11:35:47
回答 1查看 1.5K关注 0票数 1

我试图创建一个程序来查找所有长度或更长的单词,其中包含所需的字母x,而单词中的其余字母是从y中的字母中提取出来的(这是NYT中的一个谜题)。

由于我试图一步一步地做这个工作,我首先创建一个长度为>=的所有单词的单词列表,然后创建一个包含所需字母的所有单词的列表。

然后,我在列表中的每一个单词中检查每个字母,看看它们是否包含一个字母,而不是在输入的字母中,或者在输入中使用该字母的次数更多。如果发生这种情况,我会从列表中删除这个单词。

最后,我打印了所有符合条件的单词。但是,它不起作用,我也不知道为什么。我确信我在这里犯了一个真正的新手错误,但我会喜欢任何建议。非常感谢,请原谅我的可怕代码,我只学了两个星期的Python!

代码语言:javascript
复制
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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-18 09:56:52

由于您显然是Python新手,下面是关于您的代码的一些提示(这更像是代码评论而不是堆栈溢出,但是哦,好吧):

  • 不要将整个单词列表作为第一行的列表加载;这是非常内存昂贵的,而且会减慢程序的速度。一个共同的结构是 打开(‘myfile.txt’)作为f: for行的f: do_stuff_with(行) for line in f循环一次只加载一行,因此内存中一次只有一行。这样更有效率。 更广泛地说,您正在创建几个大列表:datapanswerspanswerstest。当我尝试您的代码时,因为列表太大而窒息了。(当我开始写这个答案的时候,它就开始运行了,它还没有写完。) 如果你一次检查一个单词,不管它是否匹配,把它打印出来,然后直走到下一行,那就更好了。
  • 不要使用set作为变量名。set是一个内建函数,而重写这些操作是错误的做法(因为您将以意外的方式破坏事物)。
  • 分离过滤单词列表的代码和获取用户输入的代码。我至少有两个功能:get_user_input()check_word_match(word)。这使得您的代码可重用,并且可以将用于争用用户输入(例如将长度转换为整数)的代码从匹配单词的代码中分离出来。
  • 使用较长的变量名。字符很便宜,它使您的代码更容易阅读。(例如lenreq ~> required_lengthpanswers ~> possible_answers)
  • 不清楚匹配是否区分大小写(如果是,您应该向用户说明)。如果有必要,将lower()洒在代码中将有助于使其不区分大小写。
  • 在Python3中,input()返回一个字符串,因此不需要用str()重铸它。
  • 使用普通的except:总是一个坏主意,因为您可以捕获不想捕获的错误(这捕获了所有的错误)。更好的办法是抓住你知道会引发的具体异常。 在这种情况下,我猜您抛出了一个ValueError,因为您试图删除列表中没有的项,所以应该使用except ValueError:。(虽然我不确定如何做到这一点;一旦panswerstest成为panswers的副本,我就不知道它是如何发生的。)

下面是我重写你的代码的方法:

代码语言:javascript
复制
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)

我已经将代码分为两个函数,并删除了所有的大列表。该版本运行速度要快得多(几秒钟),因为没有任何大的循环需要担心。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30890423

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档