1.创建堆
创建堆的方式分为两种:一种是先创建一个空的堆,然后再用heapqpush()往堆中添加元素;另一种是将列表转换为堆,用heapqfy()方法。
import heapq
dig = [7,2,9,12,5,3]
# 法1
heap = []
for item in dig:
heapqpush(heap, item)
# 法2
heap = heapify(dig)
print(heap[0]) # 输出最小元素
res = [heap.heapqpop() for _ in range(len(dig))]
# out: 2
# out: [2,3,5,7,9,12]
heapq 模块还有一个heapq.merge(*iterables) 方法,用于合并多个排序后的序列成一个排序后的序列, 返回排序后的值的迭代器。类似于sorted(itertools.chain(*iterables)),但返回的是可迭代的。
num1 = [32, 3, 5, 34, 54, 23, 132]
num2 = [23, 2, 12, 656, 324, 23, 54]
num1 = sorted(num1)
num2 = sorted(num2)
res = heapq.merge(num1, num2)
print(list(res))
2.访问堆内容
堆创建好后,可以通过`heapq.heappop() 函数弹出堆中最小值。如果需要删除堆中最小元素并加入一个元素,可以使用heapq.heaprepalce() 函数。
heapq.heapreplace(nums, 23)
如果需要获取堆中最大或最小的范围值,则可以使用heapq.nlargest() 或heapq.nsmallest() 函数。
nums = [1, 3, 4, 5, 2]
print(heapq.nlargest(3, nums))
print(heapq.nsmallest(3, nums))
"""
输出:
[5, 4, 3]
[1, 2, 3]
"""
这两个函数还接受一个key参数,用于dict或其他数据结构类型使用。
import heapq
from pprint import pprint
portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])
pprint(cheap)
pprint(expensive)
"""
输出:
[{'name': 'YHOO', 'price': 16.35, 'shares': 45},
{'name': 'FB', 'price': 21.09, 'shares': 200},
{'name': 'HPQ', 'price': 31.75, 'shares': 35}]
[{'name': 'AAPL', 'price': 543.22, 'shares': 50},
{'name': 'ACME', 'price': 115.65, 'shares': 75},
{'name': 'IBM', 'price': 91.1, 'shares': 100}]
"""
3.heapq应用
3.1 堆排序
该算法和sorted(iterable) 类似,但是它是不稳定的。
def heapsort(iterable):
h = []
for value in iterable:
heappush(h, value)
return [heappop(h) for i in range(len(h))]
# 输出排序后的iterable