Кажется, это работает довольно быстро, хотя для моего списка слов (235 886 из них, полный список из /usr/share/dict/words
) это занимает около 2 секунд, так что оно все еще может быть слишком медленным для вас. Но, честно говоря, как часто вы планируете запускать его по всему списку?
with open('/usr/share/dict/words', 'r') as f:
wordlist = f.readlines()
wordlist = [word.strip() for word in wordlist]
wordlist = [(word,''.join(sorted([kar for kar in word]))) for word in wordlist]
worddict = {}
for word in wordlist:
if word[1] in worddict:
worddict[word[1]].append(word[0])
else:
worddict[word[1]] = [word[0]]
for word in wordlist:
if len(worddict[word[1]]) > 1:
print (worddict[word[1]])
Результат:
['aal', 'ala']
['aam', 'ama']
['aba', 'baa']
['abac', 'caba']
['abactor', 'acrobat']
['abaft', 'bafta']
['abalone', 'balonea']
...
(27,390 lines omitted for brevity)
['ozotype', 'zootype']
['gazy', 'zyga']
['glazy', 'zygal']
[Finished in 2.1s]
Он создает словарь с отсортированными символами каждого слова в качестве ключ и список, содержащий только само это слово в качестве его начального значения . Если ключ уже присутствует в словаре, слово добавляется в его список. Тогда нужно только напечатать все списки, длина которых превышает 1 элемент.
Побочным эффектом является то, что все слова анаграммы появляются несколько раз. Это логика c для вас: incomputable
, который находится в этом списке слов, является анаграммой uncompatible
, и, следовательно, uncompatible
(по определению также в этом списке) является анаграммой incomputable
. QED.¹
Самый большой набор найденных им слов анаграммы:
['angor', 'argon', 'goran', 'grano', 'groan', 'nagor', 'orang', 'organ', 'rogan']
и интересная пара противоположностей
['misrepresentation', 'representationism']
Список даже содержит слово `pythoni c ':
['hypnotic', 'phytonic', 'pythonic', 'typhonic']
¹ После попытки: печать каждой комбинации только один раз оказалась тривиальной. Он сокращает список до 12 189 «уникальных» наборов, и проверка заняла еще 0,1 секунды.