Python进阶编程:编写更高效、优雅的Python代码
上QQ阅读APP看书,第一时间看更新

3.3.2 保留最后N个元素

在执行迭代操作或者其他操作的时候,为了满足某些业务需求,我们需要只保留最后有限的元素历史记录。

保留有限历史记录可以使用collections.deque。例如,在多行记录上做简单的文本匹配,并返回与所在行匹配的最后N行,代码如下:


from collections import deque
def search(lines, search_val, history=1):
    previous_lines = deque(maxlen=history)
        for line in lines:
            if search_val in line:
                yield line, previous_lines
            previous_lines.append(line)


if __name__ == '__main__':
    with open(r'test_file/element.txt') as f:
        for search_v, prev_lines in search(f, 'python', 2):
            for pre_line in prev_lines:
                print(pre_line, end='')
            print(f'search value is:{search_v}')

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

使用deque(maxlen=N)构造函数时会新建一个固定大小的队列。deque类的工作机制为:当新的元素加入并且队列已达到固定大小的时候,最老的元素会自动被移除,这样可以保证所查找元素的前N个元素被保留。

这里,我们也可以手动在列表上实现增加、删除等操作。不过,deque方案会更加优雅,并且运行得更快些。

一般地,deque类可以被用在任何只需要一个简单队列数据结构的场合。在使用deque类时,若不设置最大队列大小,就会得到一个无限大小队列。我们可以在队列的两端执行添加和弹出元素的操作,deque类中提供了append()、appendleft()、pop()、popleft()等函数。

使用deque类在队列两端插入或删除元素的时间复杂度都是O(1),在列表的开头插入或删除元素的时间复杂度为O(N)。