Python标准库模块——heapq

概述

heqpq模块提供了堆队列算法(也称为优先级队列算法)的实现。

堆是二叉树,其每个父节点的值都小于或等于其任何子节点。此实现使用所有k的heap [k] <= heap [2 * k + 1]和heap [k] <= heap [2 * k + 2]的数组,从零开始计数元素。为了进行比较,不存在的元素被认为是无限的。堆的有趣特性是它的最小元素始终是根堆[0]。

下面的API在两个方面与教科书堆算法不同:(a)我们使用基于零的索引。这使得节点的索引与其子节点的索引之间的关系不太明显,但由于Python使用基于零的索引,因此更适合。 (b)我们的pop方法返回的是最小的项目,而不是最大的项目(在教科书中称为“最小堆”;在文本中,“最大堆”由于其适合就地排序而更常见)。

要创建堆,请使用初始化为[]的列表,或者可以通过函数heapify()将填充的列表转换为堆。

 

API

heapq.heappush(heap,item)
将值项推入堆,保持堆不变。

heapq.heappop(heap)
弹出并从堆中返回最小的项,从而保持堆不变。如果堆为空,则会引发IndexError。要访问最小的项目而不弹出它,请使用heap [0]。

heapq.heappushpop(heap,item)
将项目推入堆中,然后弹出并从堆中返回最小的项目。组合的操作比heappush()更有效地运行,随后分别调用heappop()。

heapq.heapify(x)
将列表x在线性时间内就地转换为堆。

heapq.heapreplace(heap,item)
弹出并从堆中返回最小的项,然后推送新项。堆大小不变。如果堆为空,则会引发IndexError。

这一步操作比heapush()和heappush()效率更高,并且在使用固定大小的堆时可能更合适。弹出/推入组合始终从堆中返回一个元素,并将其替换为item。

返回的值可能大于添加的项目。如果不需要,请考虑改用heappushpop()。它的推/弹出组合返回两个值中较小的一个,而将较大的值保留在堆上。

该模块还提供了基于堆的三个通用功能。

heapq.merge(* iterables,key = None,reverse = False)
将多个排序的输入合并到一个排序的输出中(例如,合并多个日志文件中带有时间戳的条目)。返回排序后的值的迭代器。

类似于sorted(itertools.chain(* iterables)),但返回一个iterable,不会一次将数据全部拉入内存,并假定每个输入流都已排序(最小到最大)。

有两个可选参数,必须将其指定为关键字参数。

key指定一个自变量的键函数,该函数用于从每个输入元素中提取比较键。默认值为“无”(直接比较元素)。

reverse是一个布尔值。如果设置为True,则合并输入元素,就好像每个比较都被反转一样。为了实现类似于sorted(itertools.chain(* iterables),reverse = True)的行为,所有可迭代对象必须从最大到最小进行排序。

在版本3.5中进行了更改:添加了可选的key和reverse参数。

heapq.nlargest(n,iterable,key=None)
从iterable定义的数据集中返回包含n个最大元素的列表。 key(如果提供)指定一个参数的功能,该参数用于从iterable中的每个元素中提取比较键(例如,key = str.lower)。等效于:sorted(iterable,key = key,reverse = True)[:n]。

heapq.nsmallest(n,iterable,key=None)
从iterable定义的数据集中返回包含n个最小元素的列表。 key(如果提供)指定一个参数的功能,该参数用于从iterable中的每个元素中提取比较键(例如,key = str.lower)。等效于:sorted(iterable,key = key)[:n]。

对于n的较小值,后两个函数表现最佳。对于较大的值,使用sorted()函数更为有效。同样,当n == 1时,使用内置的min()和max()函数会更有效。如果需要重复使用这些功能,请考虑将可迭代对象转换为实际堆。

例子

可以通过将所有值压入堆,然后一次弹出一个最小值来实现堆排序:

>>> def heapsort(iterable):
...     h = []
...     for value in iterable:
...         heappush(h, value)
...     return [heappop(h) for i in range(len(h))]
...
>>> heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

这类似于sorted(iterable),但与sorted()不同,此实现不稳定。

堆元素可以是元组。 这对于在跟踪主记录的同时分配比较值(例如任务优先级)很有用:

>>> h = []
>>> heappush(h, (5, 'write code'))
>>> heappush(h, (7, 'release product'))
>>> heappush(h, (1, 'write spec'))
>>> heappush(h, (3, 'create tests'))
>>> heappop(h)
(1, 'write spec')

 

你可能感兴趣的:(算法与数据结构,Python)