码迷,mamicode.com
首页 > 编程语言 > 详细

python进阶(数据结构和算法[二])

时间:2015-05-11 10:52:53      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:


找到最大或者最小的N个元素

heapq模块有两个函数–nlargest()nsmallest()正好能解决我们的问题。

>>> print(heapq.nlargest(3, nums))
[43, 23, 8]
>>> print(heapq.nsmallest(3,nums))
[-1, 1, 2]

#another

import heapq

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])

print(cheap)
print(expensive)

# 输出

[{shares: 45, name: YHOO, price: 16.35}, {shares: 200, name: FB, price: 21.09}, {shares: 35, name: HPQ, price: 31.75}]
[{shares: 50, name: AAPL, price: 543.22}, {shares: 75, name: ACME, price: 115.65}, {shares: 100, name: IBM, price: 91.1}]

简单的介绍一下heapq中的方法:

import heapq
#heapq.heappush(heap,item)  #heap为定义堆,item 增加的元素;
#eg.
  heap=[]
  heapq.heappush(heap, 2) # heap = [2]
#heapq.heapify(list)        #将列表转换为堆
#eg.
   list=[5,8,0,3,6,7,9,1,4,2]
   heapq.heapify(list) 
#heapq.heappop(heap)        #删除最小的值
#eg.
  heap=[2, 4, 3, 5, 7, 8, 9, 6]
  heapq.heappop(heap) ---->heap=[3, 4, 5, 7, 9, 6, 8]
#heapq.heapreplace(heap, item)     #删除最小元素值,添加新的元素值
#eg.
  heap=[2, 4, 3, 5, 7, 8, 9, 6]
  heapq.heapreplace(heap, 11) ------>heap=[2, 3, 4, 6, 8, 5, 7, 9, 11]
#heapq.heappushpop(heap, item)     #首判断添加元素值与堆的第一个元素值对比,如果大于则删除最小元素,然后添加新的元素值,否则不更改堆
#eg.
   条件:item >heap[0]
   heap=[2, 4, 3, 5, 7, 8, 9, 6]
   heapq.heappushpop(heap, 9)---->heap=[3, 4, 5, 6, 8, 9, 9, 7]
   条件:item
   heap=[2, 4, 3, 5, 7, 8, 9, 6]
   heapq.heappushpop(heap, 9)---->heap=[2, 4, 3, 5, 7, 8, 9, 6]
#heapq.merge(...)             #将多个堆合并
#heapq.nlargest (n, heap)     #查询堆中的最大元素,n表示查询元素个数
#eg.
  heap=[2, 3, 5, 6, 4, 8, 7, 9]
  heapq.nlargest (1, heap)--->[9]
#heapq.nsmallest(n, heap)     #查询堆中的最小元素,n表示查询元素个数
#eg.
 heap=[2, 3, 5, 6, 4, 8, 7, 9]
 heapq.nlargest (1, heap)--->[2]

对不一样的数据排序使用不同的方式

  1. 当要查找的元素相对较少时,nlargestnsmallest是最合适的。
  2. 只是想找到最大最小元素,使用minmax是最合适的。
  3. 如果N和集合本身相差不大,使用排序并切片的方式是合适的(sorted(items)[:N]sorted(items)[-N:])。
  4. N相对总元素较少的时候,适合使用将数据转化成列表,元素顺序以堆的顺序排列(参照上述的heapq.heapify())。

实现优先级队列

import heapq # 堆的数据结构,通过对数时间能找到最大或最小元素
class PriorityQueue:
    def __init__(self):
        self._queue = [] #初始化的列表
        self._index = 0 # 初始化的索引,用去比较优先级相同的元素
    def push(self, item, priority):
        # 通过heappush向_queue列表中添加一个元素(元组),默认是小顶堆,因此将优先级取反;
        # 元组比较大小是逐项的,因此添加_index作为相同优先级比较的第二个比较项;永远不会比较第三项
        heapq.heappush(self._queue, (-priority, self._index, item))
        self._index += 1
    def pop(self):
        return heapq.heappop(self._queue)[-1] #弹出的是三元组(-priority, _index, Item(‘‘),只显示最后一项即可

#构造的元素类
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(barm), 4)
q.push(Item(grok), 1)
print(q.pop())
print(q.pop())
print(q.pop())
print(q.pop())

输出:

Item(bar)
Item(barm)
Item(foo)
Item(grok)

从输出中我们看出:是按照优先级输出,相同优先级的按照索引较小的先输出(因为是小顶堆并且先插入的索引值较小)

python进阶(数据结构和算法[二])

标签:

原文地址:http://blog.csdn.net/yapian8/article/details/45640605

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!