我花了好几个小时试图调试这段代码。我想获得列表中倒数第二个元素。
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
输出具有相同结构的元组列表也可以。此代码仅在迭代器上失败。
答案 0 :(得分:1)
(我想我知道发生了什么,但我是Python的新手。可以随意编辑它!)
groupby是yield
(int, iterator)
的元组。迭代器调用repeat()
来获取值。
当我调用next()
并提前通过[6,7,8]
迭代器时,这些值从repeat()
永远的输出中消失。 9
是repeat()
的下一个输出,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)
在迭代时存储值。