微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

假设我有一个大型数据列表,我想要执行某些操作,我希望有多个迭代器独立执行此操作.

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

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

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

这意味着在实践中,当我调用next(it1)时,it2也会增加,这不是我想要的行为.

这里发生了什么,有什么方法可以做我想做的事情?我在Ubuntu 14.04上使用python 2.7.

编辑:

我刚刚尝试了以下内容

gen = (e for e in [1,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,5]
>>> it = iter(x)
>>> it2 = iter(it)
>>> next(it)
1
>>> next(it2)
2
>>> it is it2
True

所以,同样,列表是可迭代的,因为它有一个返回迭代器的__iter__方法.这个迭代器也有一个__iter__方法,它应该总是返回自己,但它也有一个__next__方法.

所以,考虑一下:

>>> x = [1,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)

在这种情况下,it1和it2将是两个独立的迭代器对象.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐