2017222 Part 1 数据结构及算法(二)

Part 1 数据结构及算法(二)

1.2 heapq模块

FUNCTIONS
    heapify(...)
        Transform list into a heap, in-place, in O(len(heap)) time.    
    heappop(...)
        Pop the smallest item off the heap, maintaining the heap invariant.    
    heappush(...)
        heappush(heap, item) -> None. Push item onto heap, maintaining the heap invariant.    
    heappushpop(...)
        heappushpop(heap, item) -> value. Push item on the heap, then pop and return the smallest item
        from the heap. The combined action runs more efficiently than
        heappush() followed by a separate call to heappop().    
    heapreplace(...)
        heapreplace(heap, item) -> value. Pop and return the current smallest value, and add the new item.

1、查找最大或最小的N个元素

解决方案:heapq模块中的nlargest()和nsmallest()解决,内部利用堆排序实现,所以复杂度为O(log(N))

>>> nums=[1,2,3,4,5,6,7]
>>> heapq.nlargest(3,nums)
[7, 6, 5]
两个函数都会接受一个关键字参数,用于更复杂的参数
例如:按照protfolio中的price排序
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']) 
总结:当要查找的元素个数相对比较小的时候,函数 nlargest() 和 nsmallest() 是很合适的。如果你仅仅想查找唯一的最小或最大 (N=1) 的元素的话,那么使用 min() max() 函数会更快些。类似的,如果 的大小和集合大小接近的时候,通常先排序这个集合然后再使用切片操作会更快点 sorted(items)[:N] 或者是 sorted(items)[-
N:] 
)。需要在正确场合使用函数 nlargest() 和 nsmallest() 才能发挥它们的优势 (如果快接近集合大小了,那么使用排序操作会更好些)
2、优先级队列
import heapq

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]

# Example use
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("Should be bar:", q.pop())
print("Should be spam:", q.pop())
print("Should be foo:", q.pop())
print("Should be grok:", q.pop())
第一个  pop()  操作返回优先级最高的元素。另外注意到如果两个有着相同优先级的元素 foo  和  grok  ) ,  pop  操作按照它们被插入到队列的顺序返回的。 










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值