我有一个包含字符串的迭代器:
it = (_ for _ in ['aaxbb', 'aayybb', 'aaaaaaabb', 'ccabcavabb', 'yyaaadbb', 'yyaabb', 'a'])
我想将这些字符串分组,如果它们具有相同的第一个和最后两个字符。上例中groupby的最终结果应为:
[['aaxbb', 'aayybb', 'aaaaaaabb'],
['ccabcavabb'],
['yyaaadbb', 'yyaabb'],
['a']]
可以使用itertools.groupby
来实现这个复杂的组吗?
答案 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:])]