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 merge
ing 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.
精彩评论