[英]How to use itertools.groupby when the key value is in the elements of the iterable?
为了说明,我从一个2元组列表开始:
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
聚集具有相同密钥的iterable的连续元素。 要产生您想要的输出,您必须先对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']
我认为,获得理想结果的更简洁方法就是这样。
>>> 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()
就在唯一键上而不是整个数据集上
来自文档 :
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 ) ) ) )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.