pylib-heapq

目录

  • pylib-heapq
    • 简述
    • API
      • heapq.heapify(x)
      • heapq.heappush(heap, item)
      • heapq.heappop(heap)
      • heapq.heappushpop(heap, item)
      • heapq.heapreplace(heap, item)
      • heapq.merge(*iterables, key=None, reverse=False)
      • heapq.nlargest(n, iterable, key=None)
      • heapq.nsmallest(n, iterable, key=None)
    • 结论

简述

heapq是Python实现的优先队列算法(priority queue algorithm).
Python文档

API

headq 提供了以下几个api, 使用方式如下:

heapq.heapify(x)

把给定的 list x 进行heap化.

import random
import heapq

# create a random list
x = [random.randint(0,10) for _ in range(7)]
# make a copy of x, so that we can see the chang.
y= x.copy()
print(f'x: {x}')
print(f'y: {y}')

# heapfy x
heapq.heapify(y)
print(f'y heapfied: {y}')

输出:

x: [7, 5, 7, 5, 3, 10, 8]
y: [7, 5, 7, 5, 3, 10, 8]
y heapfied: [3, 5, 7, 5, 7, 10, 8]

根据Python文档描述, 被heapfy之后的列表满足条件:

heap[k] <= heap[2k+1] and heap[k] <= heap[2k+2] for all k, counting elements from zero.

heapq.heappush(heap, item)

向列表(heap)中插入元素(item), 插入的同时保持的列表中元素满足上述的条件.

heapq.heappop(heap)

弹出列表(heap)中的第一个元素(根据heap的性质,第一个元素即列表中的最小元素).

heapq.heappushpop(heap, item)

向列表(heap)中插入元素(item),同时弹出列表中的最小元素. 当item小于heap[0]时,返回item.

heapq.heapreplace(heap, item)

向列表(heap)中插入元素(item). 当item小于heap[0]时,返回heap[0].

示例

heap = [0, 3, 1, 8, 4, 9, 5]
print(f'original heap: {heap}')

# pop item
print(f'pop item returned: {heapq.heappop(heap)}')
print(f'after pop: {heap}')

# push an item
item = 6
heapq.heappush(heap, 6)
print(f'push item {item}, returns: {heap}')

# push and pop
# heap[0] = 1, item = 0: 0 < 1, then returned 0, the heap unchanged
item = 0
print(f'pushpop item {item}, returns: {heapq.heappushpop(heap, item)}')
print(f'after pushpop: {heap}')

# heap[0] = 1, item = 5: 5 > 1, then returned 1, the heap changed
item = 5
print(f'pushpop item {item}, returns: {heapq.heappushpop(heap, item)}')
print(f'after pushpop: {heap}')

# push and replace
# heap[0] = 3, item = 0: 0 < 3. it's a replace operation, returned is 3.
item = 0
print(f'pushreplace item {item}, returns: {heapq.heapreplace(heap, item)}')
# since the item < heap[0], the item replaces the heap[0]
print(f'after pushreplace: {heap}')

# heap[0] = 0, item = 7: 7 > 0, the returned is 0, and the heap is heapfied.
item = 7
print(f'pushreplace item {item}, returns: {heapq.heappushpop(heap, item)}')
print(f'after pushreplace: {heap}')

输出:

original heap: [0, 3, 1, 8, 4, 9, 5]
pop item returned: 0
after pop: [1, 3, 5, 8, 4, 9]
push item 6, returns: [1, 3, 5, 8, 4, 9, 6]

pushpop item 0, returns: 0
after pushpop: [1, 3, 5, 8, 4, 9, 6]
pushpop item 5, returns: 1
after pushpop: [3, 4, 5, 8, 5, 9, 6]

pushreplace item 0, returns: 3
after pushreplace: [0, 4, 5, 8, 5, 9, 6]
pushreplace item 7, returns: 0
after pushreplace: [4, 5, 5, 8, 7, 9, 6]

heapq.merge(*iterables, key=None, reverse=False)

把若干个已排好序的列表(iterables)进行合并,保证合并后的列表仍然有序.

示例

iterables = [1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25]
merged = heapq.merge(*iterables)
print(f'after merging: {list(merged)}')

iterables = ['dog', 'horse'], ['cat', 'fish', 'kangaroo']
# sort by the length of the elements
merged = heapq.merge(*iterables, key=len)
print(f'after merging: {list(merged)}')

输出:

iterables: ([1, 3, 5, 7], [0, 2, 4, 8], [5, 10, 15, 20], [], [25])
after merging: [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25]

iterables: (['dog', 'horse'], ['cat', 'fish', 'kangaroo'])
after merging: ['dog', 'cat', 'fish', 'horse', 'kangaroo']

heapq.nlargest(n, iterable, key=None)

找到列表(iterable)中最大前n个元素.

heapq.nsmallest(n, iterable, key=None)

找到列表(iterable)中前n个最小元素.

示例

iterable = [random.randint(0,10) for _ in range(7)]
print(f'iterable: {iterable}')
n = 3
print(f'first {n}th largest {heapq.nlargest(n, iterable)}')
print(f'first {n}th smallest {heapq.nsmallest(n, iterable)}')

输出:

iterable: [3, 8, 6, 5, 8, 8, 9]
first 3th largest [9, 8, 8]
first 3th smallest [3, 5, 6]

结论

heapq是一个工具包, 可以帮助实现以下功能:

  1. 找到给定列表的最小元素;
  2. 可以对列表进行排序;
  3. 对若干个排序列表进行合并,并保证合并后的序列有序;
  4. 找到列表中前n个最小/最大元素.

你可能感兴趣的:(pylib-heapq)