排序的itertools.groupby的奇怪行为

时间:2014-09-17 16:07:19

标签: python itertools

我很难理解包groupbyitertools的工作原理。我正在输入一个排序列表,但我无法访问各个组。

例如:

import itertools
sorted_types =   [ dict(type="a", value=":-o" ),
                  dict(type="a", value=":-P" ),
                  dict(type="b", value=":-(" ),
                  dict(type="b", value=":-|" ),
                ]
groups = []
for k, g in itertools.groupby(sorted_types, lambda x: x["type"]):
    groups.append(list(g))
    print k, list(g), len(list(g))
print groups

该程序的输出是

a [] 0
b [] 0
[[{'type': 'a', 'value': ':-o'}, {'type': 'a', 'value': ':-P'}], [{'type': 'b', 'value': ':-('},   {'type': 'b', 'value': ':-|'}]]

如果尺寸list(g)为0,为什么groups变量会更新?

我很困惑。

2 个答案:

答案 0 :(得分:1)

g返回的groupby是一个迭代器,如groupby docs中所述:

  

返回的组本身就是一个共享底层的迭代器   可以用groupby()迭代。

第一次打电话给list(g)时,你已经筋疲力尽了。在你调用它的所有后续时间里,你得到一个空列表,因为你在耗尽的迭代器上调用list()

要获得您期望的输出,请先存储列表,然后使用它:

import itertools
sorted_types =   [ dict(type="a", value=":-o" ),
                  dict(type="a", value=":-P" ),
                  dict(type="b", value=":-(" ),
                  dict(type="b", value=":-|" ),
                ]   
groups = []
for k, g in itertools.groupby(sorted_types, lambda x: x["type"]):
    l = list(g)
    groups.append(l)
    print k, l, len(l)
print groups

输出:

a [{'type': 'a', 'value': ':-o'}, {'type': 'a', 'value': ':-P'}] 2
b [{'type': 'b', 'value': ':-('}, {'type': 'b', 'value': ':-|'}] 2
[[{'type': 'a', 'value': ':-o'}, {'type': 'a', 'value': ':-P'}], [{'type': 'b', 'value': ':-('}, {'type': 'b', 'value': ':-|'}]]

答案 1 :(得分:1)

问题是list(g)消耗g,因此在同一groupby()次迭代期间再次调用它会返回一个空列表。

要修复,请调用一次并保留结果:

for k, g in itertools.groupby(sorted_types, lambda x: x["type"]):
    l = list(g)
    groups.append(l)
    print k, l, len(l)
print groups