保留最后 N 个元素、查找最大或最小的 N 个元素

问题:在迭代操作或者其他操作的时候,怎样只保留最后有限几个元素的历史记录?
解决方案:保留有限历史记录正是 collections.deque 大显身手的时候。比如,下面的代码
在多行上面做简单的文本匹配,并返回匹配所在行的最后 行:

 1 # 在多行上面做简单的文本匹配,并返回匹配所在行的最后 N 行:
 2 
 3 from collections import deque
 4 
 5 def search(lines, pattern, history=5):
 6     previous_lines = deque(maxlen=history)
 7     for line in lines:
 8         if pattern in line:
 9             yield line, previous_lines
10         previous_lines.append(line)
11         
12 # Example use on a file
13 if __name__ == '__main__':
14     with open(r'exam.txt') as f:
15         for line, prevlines in search(f, 'python', 5):
16             for pline in prevlines:
17                 print(pline, end='')
18             print(line, end='')
19             print('=' * 20)
20             
21     
View Code

 问题:怎样从一个集合中获得最大或者最小的 N 个元素列表?

解决方案:heapq 模块有两个函数: nlargest() 和 nsmallest() 可以完美解决这个问题。

 1 import heapq
 2 
 3 nums = [1, 8, 2, 5, 23, 18, 6, 9, -4]
 4 print(heaq.nlargest(3, nums))
 5 print(heaq.nsmallest(3, nums))
 6 
 7 portfo = [
 8     {'name': 'IBM', 'shares': 100, 'price': 91.1},
 9     {'name': 'AAPL', 'shares': 50, 'price': 543.22},
10     {'name': 'FB', 'shares': 200, 'price': 21.09},
11     {'name': 'HPQ', 'shares': 35, 'price': 31.75},
12     {'name': 'YHOO', 'shares': 45, 'price': 16.35},
13     {'name': 'ACME', 'shares': 75, 'price': 115.65}]
14 
15 # 在对每个元素进行对比的时候,会以 price 的值进行比较。
16 # lambda匿名函数表达式是起到一个函数速写的作用,允许在代码内嵌入一个函数的定义
17 cheap = heapq.nsmallest(3, protfo, key=lambda s: s['price'])
18 expensive = cheapq.nlargest(3, protfo, key=lambda s: s['price'])
View Code

当要查找的元素个数相对比较小的时候,函数 nlargest() nsmallest() 是很
合适的。如果你仅仅想查找唯一的最小或最大(N=1)的元素的话,那么使用 min()
max() 函数会更快些。类似的,如果 N 的大小和集合大小接近的时候,通常先排序这个
集合然后再使用切片操作会更快点(sorted(items)[:N] 或者是 sorted(items)[-N:]
)。需要在正确场合使用函数 nlargest() nsmallest() 才能发挥它们的优势(如果
N 快接近集合大小了,那么使用排序操作会更好些)。

原文地址:https://www.cnblogs.com/zijue/p/10174670.html