【问题标题】:Should I use a Python deque or list as a stack? [duplicate]我应该使用 Python 双端队列还是列表作为堆栈? [复制]
【发布时间】:2018-05-09 15:49:42
【问题描述】:

我想要一个可以用作堆栈的 Python 对象。使用双端队列还是列表更好?是元素少还是元素多有区别吗?

【问题讨论】:

    标签: python python-3.x list python-2.7 data-structures


    【解决方案1】:

    您的里程可能会根据您的应用程序和精确用例而有所不同,但在一般情况下,列表非常适合堆栈:

    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 移动所有 数据)。相反,双端队列追加性能是一致的,因为 它永远不会重新分配,也永远不会移动数据。

    【讨论】:

    • 如果你要对比两种解决方案,为什么要强调它们相同的部分呢?它们不是带有双端队列的“可以说” O(1) - 它们 O(1)。什么是假定的开销?有任何基准来支持这一点吗?
    • 我在性能方面得到了纠正@Ryan - 我发布了一个勘误表。
    • 请注意,引用的帖子是由 Python 核心开发人员 Raymond Hettinger 撰写的,他是 listdeque 的 C 代码的主要作者,所以他知道自己在说什么!跨度>
    • 我得到:AttributeError: 'range' object has no attribute 'append'
    • 我已经更新了答案@EduardoPignatelli,它在python 2 中是正确的,当时range 返回了list
    猜你喜欢
    • 2013-12-13
    • 2015-02-16
    • 2019-04-13
    • 2014-10-14
    • 2015-11-15
    • 2013-08-17
    • 2014-04-21
    • 2010-10-13
    • 2012-10-22
    相关资源
    最近更新 更多