保存最后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])

  

 

 

posted @ 2018-05-02 10:40  evescn  阅读(184)  评论(0编辑  收藏  举报