为什么我不能在Python中获得迭代器的倒数第二个结果?

时间:2012-05-22 05:20:31

标签: python iterator group-by

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

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))

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

2 个答案:

答案 0 :(得分:1)

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

groupby是yield (int, iterator)的元组。迭代器调用repeat()来获取值。

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

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

the_last_one = list(y)

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

答案 1 :(得分: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)

在迭代时存储值。