《Python Cookbook(第3版)中文版》——1.4 找到最大或最小的N个元素

简介:

本节书摘来自异步社区《Python Cookbook(第3版)中文版》一书中的第1章,第1.4节,作者[美]David Beazley , Brian K.Jones,陈舸 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

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

1.4.1 问题

我们想在某个集合中找出最大或最小的N个元素。

1.4.2 解决方案

heapq模块中有两个函数——nlargest()和nsmallest()——它们正是我们所需要的。例如:

import heapq

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

这两个函数都可以接受一个参数key,从而允许它们工作在更加复杂的数据结构之上。例如:

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

1.4.3 讨论

如果正在寻找最大或最小的N个元素,且同集合中元素的总数目相比,N很小,那么下面这些函数可以提供更好的性能。这些函数首先会在底层将数据转化成列表,且元素会以堆的顺序排列。例如:

>>> nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
>>> import heapq
>>> heap = list(nums)
>>> heapq.heapify(heap)
>>> heap
[-4, 2, 1, 23, 7, 2, 18, 23, 42, 37, 8]
>>>

堆最重要的特性就是heap[0]总是最小那个的元素。此外,接下来的元素可依次通过heapq.heappop()方法轻松找到。该方法会将第一个元素(最小的)弹出,然后以第二小的元素取而代之(这个操作的复杂度是O(logN),N代表堆的大小)。例如,要找到第3小的元素,可以这样做:

>>> heapq.heappop(heap)
-4
>>> heapq.heappop(heap)
1
>>> heapq.heappop(heap)
2

当所要找的元素数量相对较小时,函数nlargest()和nsmallest()才是最适用的。如果只是简单地想找到最小或最大的元素(N=1时),那么用min()和max()会更加快。同样,如果N和集合本身的大小差不多大,通常更快的方法是先对集合排序,然后做切片操作(例如,使用sorted(items)[:N]或者sorted(items)[-N:])。应该要注意的是,nlargest()和nsmallest()的实际实现会根据使用它们的方式而有所不同,可能会相应作出一些优化措施(比如,当N的大小同输入大小很接近时,就会采用排序的方法)。

使用本节的代码片段并不需要知道如何实现堆数据结构,但这仍然是一个有趣也是值得去学习的主题。通常在优秀的算法和数据结构相关的书籍里都能找到堆数据结构的实现方法。在heapq模块的文档中也讨论了底层实现的细节。

相关文章
|
5月前
|
Java 数据处理 索引
(Pandas)Python做数据处理必选框架之一!(二):附带案例分析;刨析DataFrame结构和其属性;学会访问具体元素;判断元素是否存在;元素求和、求标准值、方差、去重、删除、排序...
DataFrame结构 每一列都属于Series类型,不同列之间数据类型可以不一样,但同一列的值类型必须一致。 DataFrame拥有一个总的 idx记录列,该列记录了每一行的索引 在DataFrame中,若列之间的元素个数不匹配,且使用Series填充时,在DataFrame里空值会显示为NaN;当列之间元素个数不匹配,并且不使用Series填充,会报错。在指定了index 属性显示情况下,会按照index的位置进行排序,默认是 [0,1,2,3,...] 从0索引开始正序排序行。
423 0
|
Python Windows
Python基础教程(第3版)中文版 第18章 程序打包 (笔记)
Python基础教程(第3版)中文版 第18章 程序打包 (笔记)
188 0
|
Python
Python 选出列表中特定的元素
Python 选出列表中特定的元素
303 3
|
数据处理 索引 Python
Python列表与元素修改的操作技巧
Python列表提供了丰富的方法和技巧来进行高效的数据操作。熟练运用上述技巧,可以大大提高数据处理的效率和代码的可读性。实践中,根据具体需求灵活选择合适的方法,可以在保证代码效率的同时,也使代码更加简洁明了。
435 2
|
程序员 Python
Python 将元素添加到列表
【8月更文挑战第21天】
609 3
|
Python
【Leetcode刷题Python】剑指 Offer II 082. 含有重复元素集合的组合
解决LeetCode平台《剑指 Offer II 082. 含有重复元素集合的组合》题目的Python代码实现,通过深度优先搜索算法找出所有和为特定目标值的数字组合,并在搜索过程中通过排序和跳过重复元素来避免解集中出现重复组合。
155 2
|
索引 Python
Python中,元素
【7月更文挑战第13天】Python中,元素
212 5
|
存储 Python
Python中剩余元素(使用*)
【6月更文挑战第18天】
227 4
|
安全 Python 容器
Python中解包元素数量匹配
【6月更文挑战第21天】
217 2
|
存储 数据处理 Python
Python中解包到变量并忽略某些元素
【6月更文挑战第19天】
247 2

推荐镜像

更多