【发布时间】:2012-05-05 05:51:48
【问题描述】:
我没有真正需要改进它,这只是为了好玩。现在,在大约 20 万字的列表中,它需要大约一秒钟的时间。
我已经尽我所能地尝试优化它(使用生成器而不是列表推导产生了很大的不同),但我已经没有想法了。
你有吗?
#!/usr/bin/env python
# let's cheat at scrabble
def count_letters(word):
count = {}
for letter in word:
if letter not in count: count[letter] = 0
count[letter] += 1
return count
def spellable(word, rack):
word_count = count_letters(word)
rack_count = count_letters(rack)
return all( [word_count[letter] <= rack_count[letter] for letter in word] )
score = {"a": 1, "c": 3, "b": 3, "e": 1, "d": 2, "g": 2,
"f": 4, "i": 1, "h": 4, "k": 5, "j": 8, "m": 3,
"l": 1, "o": 1, "n": 1, "q": 10, "p": 3, "s": 1,
"r": 1, "u": 1, "t": 1, "w": 4, "v": 4, "y": 4,
"x": 8, "z": 10}
def score_word(word):
return sum([score[c] for c in word])
def word_reader(filename):
# returns an iterator
return (word.strip() for word in open(filename))
if __name__ == "__main__":
import sys
if len(sys.argv) == 2:
rack = sys.argv[1].strip()
else:
print """Usage: python cheat_at_scrabble.py <yourrack>"""
exit()
words = word_reader('/usr/share/dict/words')
scored = ((score_word(word), word) for word in words if set(word).issubset(set(rack)) and len(word) > 1 and spellable(word, rack))
for score, word in sorted(scored):
print str(score), '\t', word
【问题讨论】:
-
您错过了
spellable末尾的列表理解。既然如此,它可能会产生关键的不同:带有生成器表达式的all将在找到不正确的表达式时立即停止。 -
您是否对代码进行了分析?
-
rack_count = count_letters(rack)- 你正在为每个word计算这个。尝试之前计算一次,然后重复使用。 -
您可以更好地准备您的数据。为每个单词存储一些附加信息,例如字母计数。
-
大家好,感谢您的建议。我做了两个建议的更改,并看到了轻微的改进(十分之一秒左右)。我很惭愧地承认我从来没有学会分析 Python,我会搜索有关如何做到这一点的信息。
标签: python optimization