2011-09-25 27 views
1

首先,我通过使用合并创建了一个& b的2结果,但在合并后,我发现a的列表为空。heapq.merge:合并后的结果合并后,原来的合并为空

>>> a=merge([1,2],[3,4]) 
>>> b=merge([4,5],[6,7]) 
>>> list(a) 
[1, 2, 3, 4] 
>>> merge(a,b) 
<generator object merge at 0x365c370> 
>>> list(a) 
[] 
>>> 

list(a)的最后一个命令是空的,为什么合并(a,b)改变了?

回答

3

如文档(在你的例子在merge(a,b)输出)表示,中merge结果是一个迭代器。迭代器只能被使用一次,你不能重置或倒回它们,即使你可以,你的代码也不会这样做。 (当然,对于给定的集合,您可以有多个独立的迭代器,至少如果集合支持它的话)。

前两个merge调用返回生成器,第三个调用消耗那些生成器,因此ab之后耗尽。 (实际上,list(a)首先消耗a,所以在该片段中merge(a, b)将只能看到b的项目,但这个想法是相同的。)它不是的意思是,如果你通过例如一个列表不会被改变。但是消费一个迭代器意味着改变它。

0

heapq.merge的返回值是一个迭代器。当您将list应用于迭代器时,它将被消耗。迭代器对于一组值的一次传递是有利的。所以第二次调用list(a)时,结果为空。

0

a不是一个列表,而是一个迭代器。如果您曾经使用它,则无法再次迭代它。这与merge无关;你在这里看到同样的效果:

>>> a=merge([1,2],[3,4]) 
>>> list(a) 
[1, 2, 3, 4] 
>>> list(a)    
[] 
1
>>> a=heapq.merge([1,2],[3,4]) 
>>> b = heapq.merge([4,5], [6,7]) 
>>> list(a) 
[1, 2, 3, 4] 
>>> heapq.merge(a,b) 
<generator object merge at 0x7f083da50f50> 
>>> list(a) 
[] 
>>> list(b) 
[4, 5, 6, 7] // before you consume the iterator of b 
>>> list(b) 
[] // after you consume the iterator of b