Python cookbook(数据结构与算法)找到最大或最小的N个元素实现方法示例


Posted in Python onFebruary 13, 2018

本文实例讲述了python找到最大或最小的N个元素实现方法。分享给大家供大家参考,具体如下:

问题:想在某个集合中找出最大或最小的N个元素

解决方案:heapq模块中的nlargest()nsmallest()两个函数正是我们需要的。

>>> import heapq
>>> nums=[1,8,2,23,7,-4,18,23,42,37,2]
>>> print(heapq.nlargest(3,nums))
[42, 37, 23]
>>> print(heapq.nsmallest(3,nums))
[-4, 1, 2]
>>>

这两个函数接受一个参数key,允许其工作在更复杂的数据结构之上:

# example.py
#
# Example of using heapq to find the N smallest or largest items
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)
Python 3.4.0 (v3.4.0:04f714765c13, Mar 16 2014, 19:24:06) [MSC v.1600 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
[{'name': 'YHOO', 'price': 16.35, 'shares': 45}, {'name': 'FB', 'price': 21.09, 'shares': 200}, {'name': 'HPQ', 'price': 31.75, 'shares': 35}]
[{'name': 'AAPL', 'price': 543.22, 'shares': 50}, {'name': 'ACME', 'price': 115.65, 'shares': 75}, {'name': 'IBM', 'price': 91.1, 'shares': 100}]
>>>

如果正在寻找的最大或最小的N个元素,且相比于集合中元素的数量,N很小时,下面的函数性能更好。

这些函数首先会在底层将数据转化为列表,且元素会以堆的顺序排列。

>>> import heapq
>>> nums=[1,8,2,23,7,-4,18,23,42,37,2]
>>> heap=list(nums)
>>> heap
[1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
>>> heapq.heapify(heap) #heapify()参数必须是list,此函数将list变成堆,实时操作。从而能够在任何情况下使用堆的函数。
>>> heap
[-4, 2, 1, 23, 7, 2, 18, 23, 42, 37, 8]
>>> heapq.heappop(heap)#如下是为了找到第3小的元素
-4
>>> heapq.heappop(heap)
1
>>> heapq.heappop(heap)
2
>>>

堆(heap)最重要的特性就是heap[0]总是最小的元素。可通过heapq.heappop()轻松找到最小值,这个操作的复杂度为O(logN),N代表堆得大小。

总结:

1、当要找的元素数量相对较小时,函数nlargest()nsmallest()才最适用。
2、若只是想找到最小和最大值(N=1)时,使用min()和max()会更快。
3、若N和集合本身的大小差不多,更快的方法是先对集合排序再进行切片操作(例如使用sorted(items)[:N]sorted(items)[-N:]
4、heapq.heappush(heap, item):将item压入到堆数组heap中。如果不进行此步操作,后面的heappop()失效;
heapq.heappop(heap):从堆数组heap中取出最小的值,并返回。
heapq.heapify(list):参数必须是list,此函数将list变成堆,实时操作。从而能够在任何情况下使用堆的函数。
heapq.heappushpop(heap, item):是上述heappush和heappop的合体,同时完成两者的功能.注意:相当于先操作了heappush(heap,item),然后操作heappop(heap)
heapreplace(heap, item):是heappop(heap)和heappush(heap,item)的联合操作。注意,与heappushpop(heap,item)的区别在于,顺序不同,这里是先进行删除,后压入堆
heap,merge(*iterables)

>>> h=[]   #定义一个list
>>> from heapq import * #引入heapq模块
>>> h
[]
>>> heappush(h,5)  #向堆中依次增加数值
>>> heappush(h,2)
>>> heappush(h,3)
>>> heappush(h,9)
>>> h    #h的值
[2, 5, 3, 9]
>>> heappop(h)   #从h中删除最小的,并返回该值
2
>>> h
[3, 5, 9]
>>> h.append(1)   #注意,如果不是压入堆中,而是通过append追加一个数值
>>> h    #堆的函数并不能操作这个增加的数值,或者说它堆对来讲是不存在的
[3, 5, 9, 1]
>>> heappop(h)   #从h中能够找到的最小值是3,而不是1
3
>>> heappush(h,2)  #这时,不仅将2压入到堆内,而且1也进入了堆。
>>> h
[1, 2, 9, 5]
>>> heappop(h)   #操作对象已经包含了1
1
>>> h
[1, 2, 9, 5]
>>> heappop(h)
1
>>> heappushpop(h,4)  #增加4同时删除最小值2并返回该最小值,与下列操作等同:
2    #heappush(h,4),heappop(h)
>>> h
[4, 5, 9]
>>> a=[3,6,1]
>>> heapify(a)   #将a变成堆之后,可以对其操作
>>> heappop(a)
1
>>> b=[4,2,5]   #b不是堆,如果对其进行操作,显示结果如下
>>> heappop(b)   #按照顺序,删除第一个数值并返回,不会从中挑选出最小的
4
>>> heapify(b)   #变成堆之后,再操作
>>> heappop(b)
2
>>> a=[]
>>> heapreplace(a,3)  #如果list空,则报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: index out of range
>>> heappush(a,3)
>>> a
[3]
>>> heapreplace(a,2)  #先执行删除(heappop(a)->3),再执行加入(heappush(a,2))
3
>>> a
[2]
>>> heappush(a,5)
>>> heappush(a,9)
>>> heappush(a,4)
>>> a
[2, 4, 9, 5]
>>> heapreplace(a,6)  #先从堆a中找出最小值并返回,然后加入6
2
>>> a
[4, 5, 9, 6]
>>> heapreplace(a,1)  #1是后来加入的,在1加入之前,a中的最小值是4
4
>>> a
[1, 5, 9, 6]
>>> a=[2,4,6]
>>> b=[1,3,5]
>>> c=merge(a,b)
>>> list(c)
[1, 2, 3, 4, 5, 6]

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python使用7z解压apk包的方法
Apr 18 Python
Python的__builtin__模块中的一些要点知识
May 02 Python
浅谈Python中数据解析
May 05 Python
教你学会使用Python正则表达式
Sep 07 Python
Flask解决跨域的问题示例代码
Feb 12 Python
python做反被爬保护的方法
Jul 01 Python
Pandas0.25来了千万别错过这10大好用的新功能
Aug 07 Python
numpy中三维数组中加入元素后的位置详解
Nov 28 Python
使用python动态生成波形曲线的实现
Dec 04 Python
Selenium基于PIL实现拼接滚动截图
Apr 10 Python
Python3如何实现Win10桌面自动切换
Aug 11 Python
Python 统计序列中元素的出现频度
Apr 26 Python
python3学习笔记之多进程分布式小例子
Feb 13 #Python
Python cookbook(数据结构与算法)保存最后N个元素的方法
Feb 13 #Python
Python cookbook(数据结构与算法)从任意长度的可迭代对象中分解元素操作示例
Feb 13 #Python
Python cookbook(数据结构与算法)将序列分解为单独变量的方法
Feb 13 #Python
Python内置模块ConfigParser实现配置读写功能的方法
Feb 12 #Python
Python内置模块hashlib、hmac与uuid用法分析
Feb 12 #Python
20个常用Python运维库和模块
Feb 12 #Python
You might like
php记录代码执行时间(实现代码)
2013/07/05 PHP
php对数组排序的简单实例
2013/12/25 PHP
网站防止被刷票的一些思路与方法
2015/01/08 PHP
php实现图片上传并进行替换操作
2016/03/15 PHP
PHP简单实现模拟登陆功能示例
2017/09/15 PHP
Laravel基础_关于view共享数据的示例讲解
2019/10/14 PHP
JS 自定义函数缺省值的设置方法
2010/05/05 Javascript
对xmlHttp对象的理解
2011/01/17 Javascript
关于js类的定义
2011/06/28 Javascript
JavaScript 模拟类机制及私有变量的方法及思路
2013/07/10 Javascript
JQuery教学之性能优化
2014/05/14 Javascript
IE中JS跳转丢失referrer问题的2个解决方法
2014/07/18 Javascript
canvas雪花效果核心代码分享
2017/02/19 Javascript
利用node.js写一个爬取知乎妹纸图的小爬虫
2017/05/03 Javascript
深入浅出es6模板字符串
2017/08/26 Javascript
浅谈angular4生命周期钩子
2017/09/05 Javascript
vue源码入口文件分析(推荐)
2018/01/30 Javascript
vue中的provide/inject的学习使用
2018/05/09 Javascript
JS实现的杨辉三角【帕斯卡三角形】算法示例
2019/02/26 Javascript
详解vue2.6插槽更新v-slot用法总结
2019/03/09 Javascript
ES6的异步终极解决方案分享
2019/07/11 Javascript
JS实现滚动条触底加载更多
2019/09/19 Javascript
javascript设计模式 ? 职责链模式原理与用法实例分析
2020/04/16 Javascript
Python3中的列表,元组,字典,字符串相关知识小结
2017/11/10 Python
Python实现的多进程和多线程功能示例
2018/05/29 Python
Python爬虫学习之获取指定网页源码
2019/07/30 Python
python3实现mysql导出excel的方法
2019/07/31 Python
python实现人机猜拳小游戏
2020/02/03 Python
Python 判断时间是否在时间区间内的实例
2020/05/16 Python
Snapfish爱尔兰:在线照片打印和个性化照片礼品
2018/09/17 全球购物
Speedo速比涛德国官方网站:世界领先的泳装品牌
2019/08/26 全球购物
小学生开学感言
2014/02/28 职场文书
党风廉设责任书
2014/04/16 职场文书
校庆活动策划方案
2014/06/05 职场文书
群众路线四风对照检查材料
2014/11/04 职场文书
工伤私了协议书范本
2014/11/24 职场文书