input: ['abc', 'cab', 'cafe', 'face', 'goo']
output: [['abc', 'cab'], ['cafe', 'face'], ['goo']]
问题很简单:它按 anagrams 进行分组。订单无关紧要。
当然,我可以通过C ++(这是我的母语)来做到这一点。但是,我想知道这可以通过 Python 在单行中完成。 编辑:如果不可能,可能是2或3行。我是Python的新手。
为了检查两个字符串是否是字谜,我使用了排序。
>>> input = ['abc', 'cab', 'cafe', 'face', 'goo']
>>> input2 = [''.join(sorted(x)) for x in input]
>>> input2
['abc', 'abc', 'acef', 'acef', 'goo']
我认为通过组合map
左右可能是可行的。但是,我需要使用dict
作为哈希表。我还不知道这是否可以在一行中完成。任何提示都会被贬低!
答案 0 :(得分:6)
可读的单行解决方案:
output = [list(group) for key,group in groupby(sorted(words,key=sorted),sorted)]
例如:
>>> 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']]
这里的关键是使用itertools.groupby
from the itertools
module将列表中的项目组合在一起。
我们提供给groupby
的列表必须先进行排序,然后我们将其传递给sorted(words,key=sorted)
。这里的诀窍是sorted
可以接受一个关键函数,并根据这个函数的输出进行排序,所以我们再次传递sorted
作为关键函数,这将使用字母对字母进行排序。字符串按顺序排列。无需定义我们自己的功能或创建lambda
。
groupby
使用一个关键函数来判断项目是否应该组合在一起,我们可以再次将内置的sorted
函数传递给它。
最后要注意的是输出是键对和组对象的对,所以我们只需要使用grouper对象并使用list
函数将每个对象转换为列表。
(顺便说一句 - 我不会将你的变量input
称为隐藏the built-in input
function,尽管它可能不是你应该使用的那个。)
答案 1 :(得分:3)
难以理解的单线解决方案:
>>> 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行......)
答案 2 :(得分:2)
不是单行而是解决方案......
d = {}
for item in input:
s = "".join(sorted(item))
if not d.has_key(s):
d[s] = []
d[s].append(item)
input2 = d.values()
答案 3 :(得分:2)
可读版本:
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)
单线:
print list(list(anagrams for _, anagrams in group) for _, group in groupby(sorted(("".join(sorted(word)), word) for word in words), itemgetter(0)))
打印:
[['aaaa'], ['abc', 'cba'], ['ffag', 'gaff']]
答案 4 :(得分:1)
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)]
<强>结果:强>
[['abc', 'cab'], ['cafe', 'face'], ['foo'], ['oog', 'goo']]
您不能只使用groupby函数,因为它只将您的键函数产生相同结果的顺序元素组合在一起。
简单的解决方案就是首先使用与分组相同的功能对单词进行排序。
答案 5 :(得分:0)
Dave的答案很简洁,但O(n log(n))
所需的排序是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())
操作。
更快的解决方案是:
int aCnt=0, eCnt=0, iCnt=0, oCnt=0, uCnt=0,
consonantCnt=0;
int ffCnt = 0, flCnt = 0, fiCnt = 0;
int spaceCnt = 0, newlCnt = 0, tabCnt = 0;
char *check = new char[100];
while ( cin >> check ) {
for ( int ix = 0; ix < strlen(check); ++ix ) {
switch ( check[ix] ) {
case 'a': case 'A':
++aCnt;
break;
case 'e': case 'E':
++eCnt;
break;
case 'i': case 'I':
++iCnt;
break;
case 'o': case 'O':
++oCnt;
break;
case 'u': case 'U':
++uCnt;
break;
case ' ':
++spaceCnt;
break;
case '\t':
++tabCnt;
break;
case '\n':
++newlCnt;
break;
default:
if ( isalpha( check[ix] ) )
++consonantCnt;
break;
}
if ( check[ix] == 'f' ) {
++ix;
switch ( check[ix] ) {
case 'f':
++consonantCnt;
++ffCnt;
break;
case 'i':
++fiCnt;
++iCnt;
break;
case 'l':
++consonantCnt;
++flCnt;
break;
case 'I':
++iCnt;
break;
case 'a': case 'A':
++aCnt;
break;
case 'e': case 'E':
++eCnt;
break;
case 'o': case 'O':
++oCnt;
break;
case 'u': case 'U':
++uCnt;
break;
case ' ':
++spaceCnt;
break;
case '\t':
++tabCnt;
break;
case '\n':
++newlCnt;
break;
default:
if ( isalpha( check[ix] ) )
++consonantCnt;
break;
}
}
}
}
delete [] check;
cout << "Встретилась a: \t" << aCnt << '\n'
<< "Встретилась e: \t" << eCnt << '\n'
<< "Встретилась i: \t" << iCnt << '\n'
<< "Встретилась o: \t" << oCnt << '\n'
<< "Встретилась u: \t" << uCnt << '\n'
<< "Встретилось согласных: \t" << consonantCnt << '\n'
<< "Встретилось fl: \t" << flCnt << '\n'
<< "Встретилось fi: \t" << fiCnt << '\n'
<< "Встретилось ff: \t" << ffCnt << '\n'
<< "Встретилось символов табуляции: \t" << ffCnt << '\n'
<< "Встретилось символов пробела: \t" << ffCnt << '\n'
<< "Встретилось символов новой строки: \t" << ffCnt << '\n'
<< '\n';
答案 6 :(得分:0)
只是稍微简化了先前的工作答案,以使它更具“可读性”(提取已排序的(单词...),但步骤更简单:
>>> words = ['abc', 'eat', 'face', 'cab', 'tea', 'goo']
>>> words = sorted(words, key=sorted)
>>> words
['abc', 'cab', 'face', 'eat', 'tea', 'goo']
>>> [list(group) for key,group in groupby(words, sorted)]
[['abc', 'cab'], ['face'], ['eat', 'tea'], ['goo']]
按照 groupby 的预期,该序列处于排序顺序。