How can this Python Scrabble word finder be made faster?

前端 未结 5 843
梦如初夏
梦如初夏 2021-01-31 10:08

I have no real need to improve it, it\'s just for fun. Right now it\'s taking about a second on a list of about 200K words.

I\'ve tried to optimize it as much as I know

5条回答
  •  故里飘歌
    2021-01-31 10:50

    import trie
    
    
    def walk_trie(trie_node, rack, path=""):
        if trie_node.value is None:
            yield path
        for i in xrange(len(rack)):
            sub_rack = rack[:i] + rack[i+1:]
            if trie_node.nodes.has_key(rack[i]):
                for word in walk_trie(trie_node.nodes[rack[i]], sub_rack, path+rack[i]):
                    yield word
    
    
    if __name__ == "__main__":
        print "Generating trie... "
    
        # You might choose to skip words starting with a capital
        # rather than lower-casing and searching everything. Capitalised
        # words are probably pronouns which aren't allowed in Scrabble
    
        # I've skipped words shorter than 3 characters.
        all_words = ((line.strip().lower(), None) for line in open("/usr/share/dict/words") if len(line.strip()) >= 3)
        word_trie = trie.Trie(mapping=all_words)
        print "Walking Trie... "
        print list(walk_trie(word_trie.root, "abcdefg"))
    

    Generating the trie takes a little while, but once generated getting the list of words should be much faster than looping over a list.

    If anyone knows a way to serialise a trie that would be a great addition.

    Just to demonstrate that generating the trie is what takes the time...

       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        98333    5.344    0.000    8.694    0.000 trie.py:87(__setitem__)
       832722    1.849    0.000    1.849    0.000 trie.py:10(__init__)
       832721    1.501    0.000    1.501    0.000 {method 'setdefault' of 'dict' objects}
        98334    1.005    0.000    1.730    0.000 scrabble.py:16()
            1    0.491    0.491   10.915   10.915 trie.py:82(extend)
       196902    0.366    0.000    0.366    0.000 {method 'strip' of 'str' objects}
        98333    0.183    0.000    0.183    0.000 {method 'lower' of 'str' objects}
        98707    0.177    0.000    0.177    0.000 {len}
       285/33    0.003    0.000    0.004    0.000 scrabble.py:4(walk_trie)
          545    0.001    0.000    0.001    0.000 {method 'has_key' of 'dict' objects}
            1    0.001    0.001   10.921   10.921 {execfile}
            1    0.001    0.001   10.920   10.920 scrabble.py:1()
            1    0.000    0.000    0.000    0.000 trie.py:1()
            1    0.000    0.000    0.000    0.000 {open}
            1    0.000    0.000    0.000    0.000 trie.py:5(Node)
            1    0.000    0.000   10.915   10.915 trie.py:72(__init__)
            1    0.000    0.000    0.000    0.000 trie.py:33(Trie)
            1    0.000    0.000   10.921   10.921 :1()
            1    0.000    0.000    0.000    0.000 {method 'split' of 'str' objects}
            1    0.000    0.000    0.000    0.000 trie.py:1(NeedMore)
            1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    

提交回复
热议问题