Anagrams – Python

June 4, 2010 – 11:56 pm

Write a Python function to find all the anagrams for each of a supplied list of words. For the word dictionary to find the anagrams you could use the one found on Unix or OS X boxes at /usr/share/dict/words. So for example:

>>> for group in anagrams(['dog','cat','horse']):
...     print group
... 
['dog', 'god']
['act', 'cat']
['horse', 'shoer', 'shore']

When called without a parameter, make the function return a list of all the anagram groups in the word dictionary, ordered by the group of anagrams with the most words:

>>> for group in anagrams():
...     if len(group)>6: print len(group), group
...
9 ['ester', 'estre', 'reest', 'reset', 'steer', 'stere', 'stree', 'terse', 'tsere']
9 ['angor', 'argon', 'goran', 'grano', 'groan', 'nagor', 'orang', 'organ', 'rogan']
9 ['caret', 'carte', 'cater', 'crate', 'creat', 'creta', 'react', 'recta', 'trace']
8 ['leapt', 'palet', 'patel', 'pelta', 'petal', 'plate', 'pleat', 'tepal']
8 ['laster', 'lastre', 'rastle', 'relast', 'resalt', 'salter', 'slater', 'stelar']
7 ['dater', 'derat', 'detar', 'drate', 'rated', 'trade', 'tread']
7 ['easting', 'gainset', 'genista', 'ingesta', 'seating', 'signate', 'teasing']
7 ['darter', 'dartre', 'redart', 'retard', 'retrad', 'tarred', 'trader']
7 ['least', numberswiki.com


'setal', 'slate', 'stale', 'steal', 'stela', 'tales']
7 ['atle', 'laet', 'late', 'leat', 'tael', 'tale', 'teal']
7 ['alem', 'alme', 'lame', 'leam', 'male', 'meal', 'mela']
7 ['lapse', 'salep', 'saple', 'sepal', 'slape', 'spale', 'speal']
7 ['armet', 'mater', 'metra', 'ramet', 'tamer', 'terma', 'trame']
7 ['argel', 'ergal', 'garle', 'glare', 'lager', 'large', 'regal']
7 ['aldern', 'darnel', 'enlard', 'lander', 'lenard', 'randle', 'reland']
7 ['alert', 'alter', 'artel', 'later', 'ratel', 'taler', 'telar']
7 ['arist', 'astir', 'sitar', 'stair', 'stria', 'tarsi', 'tisar']
7 ['aril', 'lair', 'lari', 'liar', 'lira', 'rail', 'rial']
7 ['asteer', 'easter', 'reseat', 'saeter', 'seater', 'staree', 'teaser']
7 ['arpent', 'enrapt', 'entrap', 'panter', 'parent', 'pretan', 'trepan']
>>>

Can you think of an elegant (dare I say pythonic?) way to implement the anagrams function?

Here’s my attempt:

def anagrams(wordsin=None):
    f=open('/usr/share/dict/words')
    ana=dict()
    for word in f.readlines(): 
        ana.setdefault(''.join(sorted(word.rstrip())),[]).append(word.rstrip())
    if wordsin!=None: 
        return [ana.get(''.join(sorted(wordin)),[]) for wordin in wordsin]   
    else: 
        return sorted(ana.values(), key=lambda(v): (len(v)),reverse=True)
  1. 2 Responses to “Anagrams – Python”

  2. very elegant.

    one tip, for memory efficiency and simplicity, you can do the following, which reads one line at a time directly from the file, rather than creating a whole list (as in readlines).

    “for word in f:”

    in profiling my words file, that saves about 30MB of RAM (about 20%).

    one more thing, instead of “if wordsin!=None:”, you can do “if wordsin:”, which I think is more pythonic.

    By Alex Benke on Jul 21, 2010

  3. Word Maker Scrabble works good for this type of thing.

    By Joe on Aug 14, 2011

Post a Comment