Groupby复杂功能

时间:2013-12-31 15:38:16

标签: python

我有一个包含字符串的迭代器:

it = (_ for _ in ['aaxbb', 'aayybb', 'aaaaaaabb', 'ccabcavabb', 'yyaaadbb', 'yyaabb', 'a'])

我想将这些字符串分组,如果它们具有相同的第一个和最后两个字符。上例中groupby的最终结果应为:

[['aaxbb', 'aayybb', 'aaaaaaabb'],
 ['ccabcavabb'],
 ['yyaaadbb', 'yyaabb'],
 ['a']]

可以使用itertools.groupby来实现这个复杂的组吗?

2 个答案:

答案 0 :(得分:5)

根本不复杂,只需返回第一个和最后两个字符的元组:

lambda v: (v[:2], v[-2:])

或者,如果您想使用operator.itemgetter()

from operator import itemgetter

itemgetter(slice(2), slice(-2, None))

演示:

>>> from itertools import groupby
>>> from operator import itemgetter
>>> sample = ['aaxbb', 'aayybb', 'aaaaaaabb', 'ccabcavabb', 'yyaaadbb', 'yyaabb', 'a']
>>> for key, group in groupby(sample, lambda v: (v[:2], v[-2:])):
...     print list(group)
... 
['aaxbb', 'aayybb', 'aaaaaaabb']
['ccabcavabb']
['yyaaadbb', 'yyaabb']
['a']
>>> for key, group in groupby(sample, itemgetter(slice(2), slice(-2, None))):
...     print list(group)
... 
['aaxbb', 'aayybb', 'aaaaaaabb']
['ccabcavabb']
['yyaaadbb', 'yyaabb']
['a']

答案 1 :(得分:0)

在使用groupby之前先进行排序很重要。在此特定示例中,属于组的所有项目都是连续出现的,因此排序可能是可选的。但一般来说,必须在使用groupby之前对集合进行排序。

请参阅Python文档中有关相同内容的说明 https://docs.python.org/2/library/itertools.html

“groupby()的操作类似于Unix中的uniq过滤器。每次键函数的值发生变化时,它都会生成一个中断或新组(这就是为什么通常需要使用相同的键功能)。这种行为不同于SQL的GROUP BY,它聚合了常见元素而不管它们的输入顺序如何。“

sample = ['aaxbb', 'aayybb', 'aaaaaaabb', 'ccabcavabb', 'yyaaadbb', 'yyaabb', 'a', 'aaxxbb']
print [list(group) for key, group in groupby(sorted(sample), lambda x: x[:2]+x[-2:])]