开发者

heapq.merge: after merge the result of merge, the original merge is empty

First I created two results of a & b by using heapq.merge, but after mergeing a&b, I found the list of a is empty.

开发者_开发问答>>> 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)
[]
>>> 

The final result of list(a) is empty, why does merge(a,b) change a?


As the documentation (and the output on merge(a,b) in your example) indicates, the result of merge is an iterator. Iterators can only be consumed once, you can't reset or rewind them, and even if you could, your code doesn't do it. (Of course you can have several independent iterators for a given collection, at least if the collection supports it).

The first two merge calls return generators, the third call consumes those generators, and hence a and b are exhausted afterwards. (Actually, list(a) consumes a first, so in that snippet merge(a, b) will only see the items of b, but the idea is the same.) It doesn't mean to, and if you pass e.g. a list it won't be changed. But consuming an iterator means mutating it.


>>> 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


Your a is not a list but an iterator. If you use it once, you cannot iterate with it a second time. This has nothing to do with merge; you see the same effect here:

>>> a=merge([1,2],[3,4])
>>> list(a)
[1, 2, 3, 4]
>>> list(a)            
[]


The return value of heapq.merge is an iterator. When you apply list to an iterator, it is consumed. An iterator is good for one pass over the set of values. So the second time list(a) is called, the result is empty.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜