保存最后N个元素
问题:
- 希望在迭代或是其他形式的处理过程中对最后几项记录做一个有限的历史记录统计
解决方案:
- 保存有限的历史记录可算是 colletions.deque 的完美应用场景了。例如:下面的代码对一些列文本行做最简单的文本匹配操作,当发现有匹配时就输出当前的匹配行以及最后检查过的N行文本
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/5/2 09:21 # @Author : Evescn # @Site : # @File : 1.3.py # @Software: PyCharm from collections import deque def search(lines, pattern, history=5): previous_lines = deque(maxlen=history) for line in lines: if pattern in line: yield line, previous_lines previous_lines.append(line) # print(previous_lines) # Example use on a file if __name__ == '__main__': with open('somefile.txt') as f: for line, prevlines in search(f, 'python', 5): for pline in prevlines: print(pline, end='') print(line, end='') print('-'*20) ### somefile.txt test1 test2 test3 test4 test5 python pythonte test6 test7 test8 test9 test10 test11 test12 ### 输出结果: test1 test2 test3 test4 test5 python -------------------- test2 test3 test4 test5 python pythonte -------------------- deque(['test8\n', 'test9\n', 'test10\n', 'test11\n', 'test12'], maxlen=5)
讨论:
- 当编写搜索某项记录的代码时,通常会用的含义 yield 关键字的生成器函数。这将处理搜索过程的代码和使用搜索结果的代码成功解耦开来
- deque(maxlen=N) 创建了一个固定长度的队列,当有新纪录加入而队列已满时会自动移除最老的那天记录(先入先出)。例如:
>>> from collections import deque >>> q = deque(maxlen=3) >>> q.append(1) >>> q.append(2) >>> q.append(3) >>> q deque([1, 2, 3], maxlen=3) >>> q.append(4) >>> q deque([2, 3, 4], maxlen=3) >>> q.append(5) >>> q deque([3, 4, 5], maxlen=3)
- 尽管可以在列表上手动完成这样的操作(append,del),但队列这样解决方案要优雅得多,运行速度也快的多
- 当需要一个简单的队列结构时, deque 可祝你一臂之力,如果不指定队列的大小,就得到了一个无界限的队列,可以在两端执行添加和弹出操作,例如:
>>> from collections import deque >>> q = deque() >>> q.append(1) >>> q.append(2) >>> q.append(3) >>> q deque([1, 2, 3]) >>> q.appendleft(4) >>> 1 1 >>> q deque([4, 1, 2, 3]) >>> q.pop() 3 >>> q deque([4, 1, 2]) >>> q.popleft() 4 >>> q deque([1, 2])