【发布时间】:2018-05-09 15:49:42
【问题描述】:
我想要一个可以用作堆栈的 Python 对象。使用双端队列还是列表更好?是元素少还是元素多有区别吗?
【问题讨论】:
标签: python python-3.x list python-2.7 data-structures
我想要一个可以用作堆栈的 Python 对象。使用双端队列还是列表更好?是元素少还是元素多有区别吗?
【问题讨论】:
标签: python python-3.x list python-2.7 data-structures
您的里程可能会根据您的应用程序和精确用例而有所不同,但在一般情况下,列表非常适合堆栈:
append 是 O(1)
pop() 是 O(1) - 只要你不从任意位置弹出; pop() 只从最后。
对于这些操作,双端队列也是 O(1),但需要从标准库中导入模块,随机访问需要 'O(n)'。除非针对特定应用程序,否则可以提出更喜欢使用普通列表的论点。
来自this post,作者是 List 和 deque 的 C 代码的主要作者 Raymond Hettinger,似乎 deques 的性能可能比列表稍好:deques 的 pop() 操作似乎具有优势。
In [1]: from collections import deque
In [2]: s = list(range(1000)) # range(1000) if python 2
In [3]: d = deque(s)
In [4]: s_append, s_pop = s.append, s.pop
In [5]: d_append, d_pop = d.append, d.pop
In [6]: %timeit s_pop(); s_append(None)
10000000 loops, best of 3: 115 ns per loop
In [7]: %timeit d_pop(); d_append(None)
10000000 loops, best of 3: 70.5 ns per loop
deques 和 list 在性能方面的真正区别 是:
对于 appendleft() 和 popleft(),Deques 的速度为 O(1),而列表的速度为 insert(0, value) 和 pop(0) 的 O(n) 性能。
列表追加 性能受到打击和错过,因为它在引擎盖下使用 realloc()。 结果,它往往在简单的代码中具有过度乐观的时序 (因为 realloc 不必移动数据)而且真的很慢 真实代码中的计时(因为碎片强制 realloc 移动所有 数据)。相反,双端队列追加性能是一致的,因为 它永远不会重新分配,也永远不会移动数据。
【讨论】:
AttributeError: 'range' object has no attribute 'append'
range 返回了list。