数据结构和算法-3.保留最后加入的固定个数的元素

问题描述

在迭代操作或者其他操作的时候,怎样只保留最后加入的固定个数的元素?

解决方案

使用 collections.deque(maxlen=N) 建立固定大小的队列,当新的元素加入并且这个队列已满的时候, 最老的元素会自动被移除掉。

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def test_deque_maxlen():
"""测试如何使用固定大小的队列"""

q = deque(maxlen=3) # 新建一个固定大小的队列
q.append(1) # 添加元素
q.append(2)
q.append(3)

assert list(q) == [1, 2, 3] # 正好添加3个

# 再添加2个
q.append(4)
q.append(5)

# 会把老的元素移除
assert list(q) == [3, 4, 5]

举个例子:

假设现在有一个文件,我们遍历文件的每一行,但是保留最后读取的 5 行内容,应该如何做呢?

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import os
from collections import deque

relative_path = "somefile.txt"

filepath = os.path.join(os.path.dirname(os.path.realpath(__file__)), os.sep.join(relative_path.split('/')))


def search(lines, pattern, history=5):
"""
搜索关键字内容,返回最后读取的5行内容
:param lines: 一行内容
:param pattern: 匹配的关键字
:param history: 用于生成固定队列的大小
:return:
"""
previous_lines = deque(maxlen=history) # 使用 deque 新建一个固定大小的队列

for line in lines:
if pattern in line:
yield line, previous_lines # 返回一个迭代器
previous_lines.append(line)


def test_last_n():
with open(filepath) as f:
# 遍历迭代器 search
for line, prevlines in search(f, 'Python', 5):

# prevlines 首次返回的是空,因此跳过去
if prevlines:
assert len(prevlines) == 5 # 其余情况一定是固定的5个元素

# 遍历 previous_lines
for pline in prevlines:
print(pline, end='') # 打印出来
print('-' * 20)

我们在写查询元素的代码时,通常会使用包含 yield 表达式的生成器函数,这样可以将搜索过程代码和使用搜索结果代码解耦

毕小烦 wechat
「请扫一扫上面的二维码,关注老毕的微信公众号」
「您的赞赏是老毕持续创作的动力」