Python 中的 deque 是一个低级别的、高度优化的双端队列,对于实现优雅、高效的Pythonic 队列和堆栈很有用,它们是计算中最常见的列表式数据类型。
本文中,云朵君将和大家一起学习如下:
- 开始使用deque
- 有效地弹出和追加元素
- 访问deque中的任意元素
- 用deque构建高效队列
开始使用Deque
向 Python 列表的右端追加元素和弹出元素的操作,一般非常高效。如果用大 O 表示时间复杂性,那么可以说它们是 O(1)。而当 Python 需要重新分配内存来增加底层列表以接受新的元素时,这些操作就会变慢,时间复杂度可能变成 O(n)。
此外,在 Python 列表的左端追加和弹出元素的操作,也是非常低效的,时间复杂度为O(n)。
由于列表提供了 .append() 和 .pop() 这两种操作,它们可以作为堆栈和队列使用。而列表的左右端追加和弹出操作的性能问题会大大影响应用程序的整体性能。
Python 的 deque 是早在 Python 2.4 中添加到 collections 模块的第一个数据类型。这个数据类型是专门为克服 Python list 中的 .append()和 .pop() 的效率问题而设计的。
Deques是类似于序列的数据类型,被设计为堆栈和队列的一般化,它们在数据结构的两端支持高效的内存和快速的追加和弹出操作。
在 deque 对象两端的追加和弹出操作是稳定的,而且同样有效,因为 deque 是作为双链接列表实现。此外,deque 上的追加和弹出操作也是线程安全的和内存高效的。这些特性使得 deque 在Python中创建自定义栈和队列时特别有用。
如果需要保存最后看到的元素列表,也可以使用 deque,因为可以限制 deque 的最大长度。如果我们这样做了,那么一旦 deque 满了,当我们在另一端添加新的元素时,它会自动丢弃一端的元素。
下面是 deque 的主要特点的总结:
- 存储任何数据类型的元素
- 是可变数据类型
- 支持带in操作符的成员操作
- 支持索引,比如a_deque[i]
- 不支持切片,比如a_deque[0:2]
- 支持对序列和可迭代对象进行操作的内置函数,如 len() ,sorted() ,reversed() 等
- 不支持inplace 排序
- 支持正常迭代和反向迭代
- 支持使用pickle
- 确保在两端快速、内存高效和线程安全的弹出和追加操作
创建 deque 实例比较简单。只需要从 collection 中导入 deque,然后用一个可选的迭代器作为参数来调用它。
>>> from collections import deque >>> # 创建一个空的 deque >>> deque() deque([]) >>> # 使用不同的迭代器来创建 deque >>> deque((1, 2, 3, 4)) deque([1, 2, 3, 4]) >>> deque([1, 2, 3, 4]) deque([1, 2, 3, 4]) >>> deque(range(1, 5)) deque([1, 2, 3, 4]) >>> deque("abcd") deque(['a', 'b', 'c', 'd']) >>> numbers = {"one": 1, "two": 2, "three": 3, "four": 4} >>> deque(numbers.keys()) deque(['one', 'two', 'three', 'four']) >>> deque(numbers.values()) deque([1, 2, 3, 4]) >>> deque(numbers.items()) deque([('one', 1), ('two', 2), ('three', 3), ('four', 4)])
如果实例化 deque 时没有提供 iterable 作为参数,那么会得到一个空的 deque。如果提供并输入 iterable ,那么 deque 会用它的数据初始化新实例。初始化使用 deque.append() 从左到右进行。
Deque 初始化器需要以下两个可选参数。
- iterable一个提供初始化数据的迭代器。
- maxlen一个整数,指定deque的最大长度。
如前所述,如果不提供一个 iterable ,那么你会得到一个空的 deque。如果给 maxlen 提供一个值,那么你的 deque 只会存储最多的 maxlen 项。
最后,还可以使用无序的可迭代对象,如 collections 来初始化 deque。在这些情况下,不会有最终 deque 中元素的预定义顺序。
有效地弹出和追加元素
Deque 和 List 之间最重要的区别是,前者可以在序列的两端进行有效的追加和弹出操作。Deque 类实现了专门的 .popleft() 和 .appendleft() 方法,直接对序列的左端进行操作。
>>> from collections import deque >>> numbers = deque([1, 2, 3, 4]) >>> numbers.popleft() 1