Finding and grouping anagrams by Python
1 2 | input: ['abc', 'cab', 'cafe', 'face', 'goo'] output: [['abc', 'cab'], ['cafe', 'face'], ['goo']] |
问题很简单:它按变位词分组。命令无关紧要。
当然,我可以用C++来做这(这是我的母语)。但是,我想知道这可以由python在一行中完成。编辑:如果不可能,可能是2行或3行。我是Python的新手。
为了检查两个字符串是否是变位词,我使用排序。
1 2 3 4 | >>> input = ['abc', 'cab', 'cafe', 'face', 'goo'] >>> input2 = [''.join(sorted(x)) for x in input] >>> input2 ['abc', 'abc', 'acef', 'acef', 'goo'] |
号
我认为通过将
一个可读的单行解决方案:
1 | output = [list(group) for key,group in groupby(sorted(words,key=sorted),sorted)] |
。
例如:
1 2 3 4 | >>> words = ['abc', 'cab', 'cafe', 'goo', 'face'] >>> from itertools import groupby >>> [list(group) for key,group in groupby(sorted(words,key=sorted),sorted)] [['abc', 'cab'], ['cafe', 'face'], ['goo']] |
。
这里的关键是使用来自
我们提供给
最后要注意的是,输出是成对的键和组对象,所以我们只需要取grouper对象,并使用
(顺便说一句,我不会把你的变量
无法读取的单行解决方案:
1 2 3 4 | >>> import itertools >>> input = ['abc', 'face', 'goo', 'cab', 'cafe'] >>> [list(group) for key,group in itertools.groupby(sorted(input, key=sorted), sorted)] [['abc', 'cab'], ['cafe', 'face'], ['goo']] |
(好吧,如果你算一下进口额的话,实际上是2行…)
可读版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from itertools import groupby from operator import itemgetter def norm(w): return"".join(sorted(w)) words = ['abc', 'cba', 'gaff', 'ffag', 'aaaa'] words_aug = sorted((norm(word), word) for word in words) grouped = groupby(words_aug, itemgetter(0)) for _, group in grouped: print map(itemgetter(1), group) |
号
一行:
1 | print list(list(anagrams for _, anagrams in group) for _, group in groupby(sorted(("".join(sorted(word)), word) for word in words), itemgetter(0))) |
印刷品:
1 | [['aaaa'], ['abc', 'cba'], ['ffag', 'gaff']] |
。
不是一行而是一个解决方案…
1 2 3 4 5 6 7 | d = {} for item in input: s ="".join(sorted(item)) if not d.has_key(s): d[s] = [] d[s].append(item) input2 = d.values() |
1 2 3 4 5 | from itertools import groupby words = ['oog', 'abc', 'cab', 'cafe', 'face', 'goo', 'foo'] print [list(g) for k, g in groupby(sorted(words, key=sorted), sorted)] |
结果:
1 | [['abc', 'cab'], ['cafe', 'face'], ['foo'], ['oog', 'goo']] |
。
不能只使用groupby函数,因为它只将键函数产生相同结果的顺序元素分组在一起。
简单的解决方案就是首先使用与分组相同的函数对单词进行排序。
戴夫的回答很简洁,但是
1 2 3 4 5 6 7 8 9 | from collections import defaultdict def group_anagrams(strings): m = defaultdict(list) for s in strings: m[tuple(sorted(s))].append(s) return list(m.values()) |