1.3 保留最后N个元素
问题描述
在迭代操作时,怎样只保留最后有限几个元素的历史记录?
解决方案
数据结构:collections.deque
例如,下面的代码在文本的每行做匹配,并返回匹配所在行之前的最后N行:
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)
if __name__ == '__main__':
with open(r'test.txt') as f:
for line, prevlines in search(f, 'python', 5):
for pline in prevlines:
print(pline, end='')
print('-' * 20)
讨论
我们在写查询元素的代码时,通常会使用包含yield表达式的生成器函数,也就是上面示例代码中的那样。这样可以将搜索过程代码和使用搜索结果代码解耦。
deque是一个双向队列,deque(maxlen=N)会新建一个固定大小的队列,当新元素加入并且这个队列已满时,最老的一个元素会被移除。
deque类可以被用在任何你只需要一个简单队列数据结构的场合。如果不设置最大队列的大小,那么就可以得到一个可以存储无限多数据的队列,deque可以在队列的两端执行添加和弹出元素的操作:
q = deque()
q.append(1)
q.append(2)
# deque([1, 2])
q.appendleft(4)
# deque([4, 1, 2])
p = q.pop()
# p = 2, q = deque([4, 1])
p = q.popleft()
# p = 4, q = deque([1])
在队列两端插入或删除元素的时间复杂度都是O(1),而在列表开头插入或删除元素的时间复杂度为O(N)(因为后面的元素都要跟着往后或往前移动)。
总结
本节介绍了数据结构——双向队列deque,并示范了如何使用deque保留有限历史记录。

浙公网安备 33010602011771号