如何在迭代器的元素中使用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']
从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))))
删除括号内的空格会让我感到温暖和模糊内部;) – 2010-08-09 14:36:47
我是一个信徒在\ 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()
只是在唯一的密钥,而不是整个数据集
我想'grp'是'itertool._grouper'对象。我可以用'_grouper'做些什么'builtin'动作?我看到你把它当作一个'iterable'来对待?整齐! – Kit 2010-08-09 13:52:20
@Kit:我认为关于'grp'的主要有用的事实是它是一个'iterable'。在你提到它之前,我不知道它是一个'itertools._grouper'对象。这似乎是鸭式打字便利的一个很好的例子。我们不需要知道'grp'的类型,只需要它实现'iterable'接口。 – unutbu 2010-08-09 18:18:37
+1''itemgetter' – Krastanov 2013-03-30 14:35:48