1

我花了几个小时试图调试这段代码。我想获取列表的倒数第二个元素。

for x, y in itertools.groupby(range(0,10), lambda x: int(x / 3)):
    print("the group's key is %d and values are %s" % (x, ','.join(map(str,y))))

temp = itertools.groupby(range(0,10), lambda x: int(x / 3))
the_last_one = None
second_to_last = None
for x,y in temp:
    second_to_last = the_last_one
    the_last_one = y
print(next(iter(second_to_last)))

为了演示,第一部分的输出是:

the group's key is 0 and values are 0,1,2
the group's key is 1 and values are 3,4,5
the group's key is 2 and values are 6,7,8
the group's key is 3 and values are 9

第二部分的目标是输出倒数第二组中的第一个元素。我期望6但相反,我得到了异常StopIteration。如果我将最后一行更改为:

print(next(the_last_one))

然后我得到了预期的结果9groupby也使用与作品输出具有相同结构的元组列表。此代码仅在迭代器上失败。

4

2 回答 2

1

(我想我知道发生了什么,但我是 Python 新手。请随意编辑!)

groupbyyield(int, iterator). 迭代器调用repeat()来获取值。

当我调用next()并提前通过[6,7,8]迭代器时,这些值从repeat() 永远的输出中消失了。 9是下一个输出,repeat()而 second_to_last 是一个迭代器,指向迭代器未保存的过去。(不确定这部分...)

将迭代器保存在 second_to_last 是不够的,我需要保存这些值。解决方案是将行更改为:

the_last_one = list(y)

list()强制将迭代器的结果保存到内存中。

于 2012-05-22T05:20:31.413 回答
1

根据以下文档itertools.groupby

返回的组本身就是一个迭代器,它与 groupby() 共享底层迭代。因为源是共享的,所以当 groupby() 对象前进时,之前的组不再可见。因此,如果以后需要该数据,则应将其存储为列表:

这意味着在您第一次迭代时会消耗可迭代对象。

改变

for x,y in temp:
    second_to_last = the_last_one
    the_last_one = y

for x,y in temp:
    second_to_last = the_last_one
    the_last_one = list(y)

在迭代时存储值。

于 2012-05-22T05:54:44.613 回答