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将是两个独立的迭代器对象.

相关文章

功能概要:(目前已实现功能)公共展示部分:1.网站首页展示...
大体上把Python中的数据类型分为如下几类: Number(数字) ...
开发之前第一步,就是构造整个的项目结构。这就好比作一幅画...
源码编译方式安装Apache首先下载Apache源码压缩包,地址为ht...
前面说完了此项目的创建及数据模型设计的过程。如果未看过,...
python中常用的写爬虫的库有urllib2、requests,对于大多数比...