gpt4 book ai didi

python - 从生成器创建迭代器返回相同的对象

转载 作者:太空宇宙 更新时间:2023-11-03 13:28:00 27 4
gpt4 key购买 nike

假设我有一个大型数据列表,我想对其执行一些操作,并且我希望有多个迭代器独立执行此操作。

data = [1,2,3,4,5]
generator = ((e, 2*e) for e in data)
it1 = iter(generator)
it2 = iter(generator)

我希望这些迭代器是不同的代码对象,但是 it1 is it2 返回 True...更令人困惑的是,对于以下生成器也是如此:

# copied data
gen = ((e, 2*e) for e in copy.deepcopy(data))
# temp object
gen = ((e, 2*e) for e in [1,2,3,4,5])

这实际上意味着当我调用 next(it1) 时,it2 也会递增,这不是我想要的行为。

这是怎么回事,有什么方法可以做我想做的事吗?我在 Ubuntu 14.04 上使用 python 2.7。

编辑:

我也刚刚尝试了以下方法:

gen = (e for e in [1,2,3,4,5])
it = iter(gen)
next(it)
next(it)
for e in gen:
print e

打印 3 4 5... 显然生成器只是我想象的一个更受限制的概念。

最佳答案

生成器是迭代器。所有行为良好的迭代器都有一个 __iter__ 方法,应该简单地

return self

来自docs

The iterator objects themselves are required to support the following two methods, which together form the iterator protocol:

iterator.__iter__() Return the iterator object itself. This is required to allow both containers and iterators to be used with the for and in statements. This method corresponds to the tp_iter slot of the type structure for Python objects in the Python/C API.

iterator.__next__() Return the next item from the container. If there are no further items, raise the StopIteration exception. This method corresponds to the tp_iternext slot of the type structure for Python objects in the Python/C API.

因此,考虑另一个迭代器示例:

>>> x = [1, 2, 3, 4, 5]
>>> it = iter(x)
>>> it2 = iter(it)
>>> next(it)
1
>>> next(it2)
2
>>> it is it2
True

所以,再说一遍,列表是可迭代的,因为它有一个返回迭代器__iter__方法。这个迭代器还有一个 __iter__ 方法,它应该总是返回自己,但它也有一个 __next__ 方法。

所以,考虑:

>>> x = [1, 2, 3, 4, 5]
>>> it = iter(x)
>>> hasattr(x, '__iter__')
True
>>> hasattr(x, '__next__')
False
>>> hasattr(it, '__iter__')
True
>>> hasattr(it, '__next__')
True
>>> next(it)
1
>>> next(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not an iterator

对于生成器:

>>> g = (x**2 for x in range(10))
>>> g
<generator object <genexpr> at 0x104104390>
>>> hasattr(g, '__iter__')
True
>>> hasattr(g, '__next__')
True
>>> next(g)
0

现在,您正在使用生成器表达式。但是你可以只使用生成器函数。完成您正在做的事情的最直接的方法就是使用:

def paired(data):
for e in data:
yield (e, 2*e)

然后使用:

it1 = paired(data)
it2 = paired(data)

在这种情况下,it1it2 将是两个独立的迭代器对象。

关于python - 从生成器创建迭代器返回相同的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52020719/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com