# 怎样从一个集合中获得最大或者最小的 N 个元素列表?
import heapq
nums = (1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2)
print(heapq.nlargest(1, nums)) # Prints [42, 37, 23]
print(heapq.nsmallest(3, nums)) # Prints [-4, 1, 2]
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(1, portfolio, key=lambda s: s['price']) # 上面代码在对每个元素进行对比的时候,会以 price 的值进行比较
expensive = heapq.nlargest(1, portfolio, key=lambda s: s['price'])
print(cheap)
print(expensive)
# print(min(nums))
# print(max(nums))
nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
heapq.heapify(nums) # 转换list成为heapq(必须要为list)
print(nums) # 堆数据结构最重要的特征是 heap[0] 永远是最小的元素。并且剩余的元素可以很
# 容易的通过调用 heapq.heappop() 方法得到,该方法会先将第一个元素弹出来,然后
# 用下一个最小的元素来取代被弹出元素
min = heapq.heappop(nums) # 需要先转换成堆结构
print(min)
# 总结:当要查找的元素个数相对比较小的时候,函数 nlargest() 和 nsmallest() 是很
# 合适的。如果你仅仅想查找唯一的最小或最大 (N=1) 的元素的话,那么使用 min() 和
# max() 函数会更快些。类似的,如果 N 的大小和集合大小接近的时候,通常先排序这
# 个集合然后再使用切片操作会更快点 ( sorted(items)[:N] 或者是 sorted(items)[-
# N:] )。需要在正确场合使用函数 nlargest() 和 nsmallest() 才能发挥它们的优势 (如果
# N 快接近集合大小了,那么使用排序操作会更好些)。
class PriorityQueue:
'''
优先级队列
'''
def __init__(self):
self._queue = []
self._index = 0
def push(self,item,priority):
heapq.heappush(self._queue,(-priority,self._index,item))
self._index+=1
def pop(self):
return heapq.heappop(self._queue)[-1]
def __str__(self):
return str(self._queue)
class Item:
def __init__(self,name):
self.name = name
def __repr__(self):
return 'Item({!r})'.format(self.name)
q = PriorityQueue()
q.push(Item('foo'), 1)
q.push(Item('bar'), 5)
q.push(Item('spam'), 4)
q.push(Item('grok'), 1)
print(q)
print(q.pop())
print(q.pop())
print(q.pop())
print(q.pop())
#函 数 heapq.heappush() 和
# heapq.heappop() 分别在队列 queue 上插入和删除第一个元素,并且队列 queue 保证
# 第一个元素拥有最小优先级 (1.4 节已经讨论过这个问题)。 heappop() 函数总是返回”
# 最小的” 的元素,这就是保证队列 pop 操作返回正确元素的关键。另外,由于 push 和
# pop(会对元组得数据进行比较) 操作时间复杂度为 O(log N),其中 N 是堆的大小,因此就算是 N 很大的时候它们
# 运行速度也依旧很快。
# 在上面代码中,队列包含了一个 (-priority, index, item) 的元组。优先级为负
# 数的目的是使得元素按照优先级从高到低排序。这个跟普通的按优先级从低到高排序
# 的堆排序恰巧相反。
# index 变量的作用是保证同等优先级元素的正确排序。通过保存一个不断增加的
# index 下标变量,可以确保元素按照它们插入的顺序排序。而且, index 变量也在相
# 同优先级元素比较的时候起到重要作用
aa= [(0,1,2),(1,2,2),(0,1,3),(0,1,4),(2,1,3)]
heapq.heapify(aa)
a1= heapq.heappop(aa)
print(a1)
a2= heapq.heappop(aa)
print(a2)
a3= heapq.heappop(aa)
print(a3)
a4= heapq.heappop(aa) # heappop会根据元组得大小进行弹出
print(a4)
result:
(0, 1, 2)
(0, 1, 3)
(0, 1, 4)
(1, 2, 2)