如何在迭代器的元素中使用itertools.groupby?

问题描述:

为了说明这一点,我开始用2元组的列表:如何在迭代器的元素中使用itertools.groupby?

import itertools 
import operator 

raw = [(1, "one"), 
     (2, "two"), 
     (1, "one"), 
     (3, "three"), 
     (2, "two")] 

for key, grp in itertools.groupby(raw, key=lambda item: item[0]): 
    print key, list(grp).pop()[1] 

产量:

1 one 
2 two 
1 one 
3 three 
2 two 

在试图调查为何:

for key, grp in itertools.groupby(raw, key=lambda item: item[0]): 
    print key, list(grp) 

# ---- OUTPUT ---- 
1 [(1, 'one')] 
2 [(2, 'two')] 
1 [(1, 'one')] 
3 [(3, 'three')] 
2 [(2, 'two')] 

即使这会给我相同的输出:

for key, grp in itertools.groupby(raw, key=operator.itemgetter(0)): 
    print key, list(grp) 

我想要得到的东西,如:

1 one, one 
2 two, two 
3 three 

我想这是因为关键是列表内部的元组内的时候,其实元组被搬来搬去为一体。有没有办法达到我想要的结果?也许groupby()不适合这个任务?

groupby集群连续具有相同键的可迭代元素。 要产生你想要的输出,你必须首先排序raw

for key, grp in itertools.groupby(sorted(raw), key=operator.itemgetter(0)): 
    print key, map(operator.itemgetter(1), grp) 

# 1 ['one', 'one'] 
# 2 ['two', 'two'] 
# 3 ['three'] 
+0

我想'grp'是'itertool._grouper'对象。我可以用'_grouper'做些什么'builtin'动作?我看到你把它当作一个'iterable'来对待?整齐! – Kit 2010-08-09 13:52:20

+0

@Kit:我认为关于'grp'的主要有用的事实是它是一个'iterable'。在你提到它之前,我不知道它是一个'itertools._grouper'对象。这似乎是鸭式打字便利的一个很好的例子。我们不需要知道'grp'的类型,只需要它实现'iterable'接口。 – unutbu 2010-08-09 18:18:37

+0

+1''itemgetter' – Krastanov 2013-03-30 14:35:48

docs

GROUPBY的操作()类似于 UNIX中的uniq的过滤器。它 生成一个中断或新组每 时间键功能 的值更改(这就是为什么它通常是 需要使用相同的键功能排序数据 )。 行为不同于SQL的GROUP BY ,它聚合公共元素 ,而不管它们的输入顺序如何。

既然你是按字典反正排序元组,你可以叫sorted

for key, grp in itertools.groupby(sorted(raw), key = operator.itemgetter(0)): 
    print(key, list(map(operator.itemgetter(1), list(grp)))) 
+6

删除括号内的空格会让我感到温暖和模糊内部;) – 2010-08-09 14:36:47

+1

我是一个信徒在\ t \ n \ n,空白的主。他告诉我PEP-8是错误的,而且这个世界需要更多的空白! – katrielalex 2010-08-09 15:00:01

我认为一个更清洁的方式来获得您想要的结果是这样的。

>>> from collections import defaultdict 
>>> d=defaultdict(list) 
>>> for k,v in raw: 
... d[k].append(v) 
... 
>>> for k,v in sorted(d.items()): 
... print k, v 
... 
1 ['one', 'one'] 
2 ['two', 'two'] 
3 ['three'] 

建设d为O(n),现在sorted()只是在唯一的密钥,而不是整个数据集