Python使用heapq实现小顶堆(TopK大)、大顶堆(BtmK小) | 四号程序员

Python使用heapq实现小顶堆(TopK大)、大顶堆(BtmK小)

需1求:给出N长的序列,求出TopK大的元素,使用小顶堆,heapq模块实现。

01 import heapq
02 import random
03  
04 class TopkHeap(object):
05     def __init__(self, k):
06         self.k = k
07         self.data = []
08  
09     def Push(self, elem):
10         if len(self.data) < self.k:
11             heapq.heappush(self.data, elem)
12         else:
13             topk_small = self.data[0]
14             if elem > topk_small:
15                 heapq.heapreplace(self.data, elem)
16  
17     def TopK(self):
18         return [x for x in reversed([heapq.heappop(self.data) for x in xrange(len(self.data))])]
19  
20 if __name__ == "__main__":
21     print "Hello"
22     list_rand = random.sample(xrange(1000000), 100)
23     th = TopkHeap(3)
24     for i in list_rand:
25         th.Push(i)
26     print th.TopK()
27     print sorted(list_rand, reverse=True)[0:3]

上面的用heapq就能轻松搞定。

变态的需求来了:给出N长的序列,求出BtmK小的元素,即使用大顶堆。

heapq在实现的时候,没有给出一个类似Java的Compartor函数接口或比较函数,开发者给出了原因见这里:http://code.activestate.com/lists/python-list/162387/

于是,人们想出了一些很NB的思路,见:http://stackoverflow.com/questions/14189540/python-topn-max-heap-use-heapq-or-self-implement

我来概括一种最简单的:

将push(e)改为push(-e)、pop(e)改为-pop(e)。

也就是说,在存入堆、从堆中取出的时候,都用相反数,而其他逻辑与TopK完全相同,看代码:

01 class BtmkHeap(object):
02     def __init__(self, k):
03         self.k = k
04         self.data = []
05  
06     def Push(self, elem):
07         # Reverse elem to convert to max-heap
08         elem = -elem
09         # Using heap algorighem
10         if len(self.data) < self.k:
11             heapq.heappush(self.data, elem)
12         else:
13             topk_small = self.data[0]
14             if elem > topk_small:
15                 heapq.heapreplace(self.data, elem)
16  
17     def BtmK(self):
18         return sorted([-x for x in self.data])

经过测试,是完全没有问题的,这思路太Trick了……

Python使用heapq实现小顶堆(TopK大)、大顶堆(BtmK小)的更多相关文章

  1. 数据结构:堆排序 (python版) 小顶堆实现从大到小排序 | 大顶堆实现从小到大排序

    #!/usr/bin/env python # -*- coding:utf-8 -*- ''' Author: Minion-Xu 小堆序实现从大到小排序,大堆序实现从小到大排序 重点的地方:小堆序 ...

  2. python中heapq堆的讲解

    堆的定义: 堆是一种特殊的数据结构,它的通常的表示是它的根结点的值最大或者是最小. python中heapq的使用 列出一些常见的用法: heap = []#建立一个常见的堆 heappush(hea ...

  3. Python中heapq与优先队列【详细】

    本文始发于个人公众号:TechFlow, 原创不易,求个关注 今天的文章来介绍Python当中一个蛮有用的库--heapq. heapq的全写是heap queue,是堆队列的意思.这里的堆和队列都是 ...

  4. python中heapq对dict进行排序

    问题: 想从以下形式的dict中取value最大的2个key-value的key dict_num_num = {0: 0.07374631268436578, 1: 0.16307692307692 ...

  5. PTA 最小堆插入元素和删除堆顶(无哨兵元素) (20分)

    PTA 最小堆插入元素和删除堆顶(无哨兵元素) (20分) 对于给定的最小堆(优先队列),分别实现插入元素和删除堆顶的函数. 函数接口定义: int insertIntoHeap(struct Hea ...

  6. python 关于heapq模块的随笔

    heapq模块提供了很多高级功能可以通过help(heapq)查看详细文档: 要点: 1优先级队列让我们可以按照重要程度来处理元素,而不是先进先出 2使用heapq可以应对长列表,因为heap不是复杂 ...

  7. Java堆外内存之三:堆外内存回收方法

    一.JVM内存的分配及垃圾回收 对于JVM的内存规则,应该是老生常谈的东西了,这里我就简单的说下: 新生代:一般来说新创建的对象都分配在这里. 年老代:经过几次垃圾回收,新生代的对象就会放在年老代里面 ...

  8. 【最短路Dijistra】【一般堆优化】【配对堆优化】

    突然觉得堆优化$O(log_n)$的复杂度很优啊,然而第n次忘记了$Dijistra$怎么写QAQ发现之前都是用的手写堆,这次用一下$stl$ #include<bits/stdc++.h> ...

  9. 二叉堆复习(包括d堆)

    要期中考了……我真的是什么也不会啊,书都没看过TAT. 好吧整理一下二叉堆,这里就以最大堆为例好了. 首先二叉堆其实是一棵CBT,满足父节点的键值大于左右子节点的键值(wikipedia把这个叫键值, ...

随机推荐

  1. 调试出不来 断点不起作用 调试技巧 MyEclipse进不了调试

    1:今天遇到了web项目调试总是不起作用,后来经人指点才知,当调试的断点仅仅是一个小圆圈时断点是不起作用的,这是可以重启下tomcat服务器再重新访问断点才会起作用,这是你会发现断点的小圆点左下角有个 ...

  2. java.lang.NoClassDefFoundError: ognl/PropertyAccessor解决的方法

    本来不想为这个专门写一篇文章的,可是发现这么简单的一个问题居然没有人好好回答过.从方便搜索的角度考虑,特意取了这么一个题目. 事实上解决方法就是将ognl的jar包增加就可以. 比方我用的是ognl3 ...

  3. Cocos2d-x 3.2 大富翁游戏项目开发-第七部分 获取角色路径_3

    点击下载代码   http://download.csdn.net/detail/lideguo1979/8291803 新建一个类RouteNavigation,定义getPath()方法.用来获取 ...

  4. Android Drawable 与 LayerList综合汇总

    先看需求.要求这样的效果 上代码 <?xml version="1.0" encoding="utf-8"? > <layer-list xm ...

  5. fcntl()

      fcntl() F_GETFL---------------------------------------------        将文件状态标志作为函数值返回. 文件状态标志:        ...

  6. opengl学习笔记(二)

    这段时间终于接触到一点点shader了,应该说shader是非常有用的东西吧,它就是能够把一些固定渲染管线的东西改变了,按照自己的意愿进行渲染,这样的话图形就可以自由发挥了. 我也只是试验了一下sha ...

  7. SRM589 DV1 250 回文字符串

    其实这道题挺简单的,不过刚开始我钻了一个错误的死胡同.想明白之后才发现. 题目要求用最少的时间来将一个字符串变成回文字符串.(具体题目参看topcoder srm589 DV1 250分值的题目,不便 ...

  8. 中转server

    中转传输概要设计 中转传输的消息架构为模拟MFC的消息架构,请參考我的上一篇文章. 1. 概述 中转server採用事件驱动的方式,与socket结合.其层次例如以下: 在事件驱动层中,将相关消息发送 ...

  9. C#中一些易混知识的比较

     Equals 和==的区别         C#中有两种不同的相等:引用相等和值相等         ==是比较两个变量的值是否相同或两个引用是不是指向同一个内存地址.         Equals ...

  10. 新发现的Cyberduck(映射网盘)和zsuncloud(硬件产品很新潮),群辉nas的确好用(购买链接)

    https://cyberduck.io/?l=en http://www.zsuncloud.com/ 群辉nas的确好用啊在哪里可以买到?官网 淘宝也可以自己做黑群晖 先用xpenoboot is ...