所有排列不仅显示英语

时间:2015-04-21 09:25:08

标签: python flask

我正在尝试找一种解决字谜的简单方法,并在返回页面上显示那些英文单词的字谜。目前,这显示了求解器页面上的排列并且有些有效,但我想展示那些只是实际单词的那些。

非常感谢任何建议。

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'GET':
        return render_template('main.html')
    else:
        myLetters = request.form['letters']
        myLetters = ''.join(sorted(myLetters))
        myLetters = myLetters.strip()
        myWords = []
        myLetterList = list(myLetters)
        lettersLength = len(myLetterList)
        myWords = [''.join(result) for result in permutations(myLetters)]

        with open("/usr/share/dict/words") as defaultWords:
            for word in myWords:
                if word not in defaultWords:
                    myWords.remove(word)

        return render_template('solver.html', myLetters = myLetters, myWords = myWords)

2 个答案:

答案 0 :(得分:1)

问题在于:

if word not in defaultWords:

对文件使用in运算符会产生意外结果。

文件不支持__contains__,但它们的行为类似于行序列,因此if word in file只是在行上迭代并产生意想不到的效果:

In [1]: f = open('/usr/share/dict/words')

In [2]: 'black\n' in f
Out[2]: True

In [3]: 'black\n' in f
Out[3]: False

In [4]: f.seek(0)

In [5]: 'black\n' in f
Out[5]: True

相反,在文件中创建一组所有单词(使用strip清除额外的空格):

with open('/usr/share/dict/words') as f:
    words = set(line.strip() for line in f)

并使用words进行查找。


编辑:一旦你有了这个集合,你可能会想做类似的事情:

for word in myWords:
    if word not in words:
        myWords.remove(word)

但是在迭代时编辑列表是bad idea。相反,您可以迭代副本:

for word in list(myWords):
    if word not in words:
        myWords.remove(word)

瞧,它有效。但是,嘿,words现在是一个集合,所以为什么要打扰一个循环呢?您可以使用set.intersection并简单地说:

return words.intersection(myWords)

练习:如何避免一次将整个列表myWords保留在内存中?

答案 1 :(得分:0)

再次感谢@Kos。我的解决方法有所不同。虽然它不是非常漂亮,但它的工作原理。我不得不在部署期间将/ usr / share / dict / words更改为包中包含的文件,但除此之外它还可以。如果你喜欢anagrams.mnickey.com或这里的回购github.com/mnickey/anagrams

,你可以在这里看到它
""" This is setting up the control dictionary to read against """
from collections import defaultdict
words = defaultdict(list)
with open("dictionary") as f:
    for word in f:
        word=word.strip()
        words[''.join(sorted(word))].append(word)

@app.route('/', methods=['GET', 'POST'])
@app.route('/anagrams/', methods=['GET', 'POST'])
def index():
    if request.method == 'GET':
        return render_template('main.html')
    else:
        #this is the original set of letters that I want anagrams for
        myLetters = request.form['letters']
        # some cleanup on those letters
        myLetters = ''.join(sorted(myLetters))
        # then assign those letters to 'word'
        word = myLetters.strip().lower()

        """ This is where I need to check the letter sets against the control group """
        myWords =  words[''.join(sorted(word))]
        return render_template('solver.html', myLetters = myLetters, myWords = myWords)