heapq.merge()如何与无限生成器一起使用?

时间:2020-07-08 11:18:53

标签: python merge heap priority-queue heapq

我想了解heapq.merge()与无限生成器一起工作的方式。考虑以下示例:

>>> from heapq import merge
>>> from itertools import count
>>> m = merge(count(0, 2), count(1, 2))
>>> for _ in range(10):
...     print(next(m))
...
0
1
2
3
4
5
6
7
8
9 

文档指出它不会立即将数据全部拉入内存。但是它如何消耗每个无限生成器?

1 个答案:

答案 0 :(得分:1)

这种功能的非常简单实现如下所示。但是请注意,为简单起见,它不处理任何特殊(且不太特殊)的情况,例如空的或用尽的可迭代项。

def merge(*iterables):
    heap = [(next(it), i) for i, it in enumerate(iterables)]
    heapq.heapify(heap)
    while heap:
        val, i = heapq.heappop(heap)
        yield val
        heapq.heappush(heap, (next(iterables[i]), i))

它是这样的:

  • 从每个 sorted 可迭代对象中获取第一个元素,以及列表中该可迭代对象的索引
  • 从该堆中产生下一个最小的元素
  • 将可迭代对象中的下一个元素添加到堆中,索引与刚刚产生的索引相同。

实际的实现要复杂一些,但似乎大致相同。您可以使用heapq.__file__(在我的系统上为/usr/lib/python3.6/heapq.py)获取本地源的位置,并进行检查。