【问题标题】:Effective queue/linked list in PythonPython中的有效队列/链表
【发布时间】:2026-01-31 02:05:03
【问题描述】:

我需要在 Python 中编写事件日历,它允许在任何位置粘贴事件并作为 FIFO(从左侧弹出元素)工作。

Python collections.deque 可以高效地作为 FIFO 工作,但它不允许在当前元素之间粘贴元素。

另一方面,Python list 允许插入到中间,但 popleft 效率低。

那么,有什么妥协吗?

UPD 这种结构可能比队列更接近链表。标题已更改。

【问题讨论】:

  • Afaik 没有一个课程可以同时有效地完成这两个任务。你已经搞定了:list 可以插入到任何位置,deque 可以左右弹出/插入/扩展。
  • list 在中间的插入渐近与 popleft 一样低效。

标签: python queue deque


【解决方案1】:

只是一个想法 - 您可以使用 heapq 来维护您的事件列表。作为堆中元素的优先级/键,您可以使用事件的时间戳。

【讨论】:

    【解决方案2】:

    你可以看看blist。引用自他们的网站:

    blist 是 Python 列表的直接替代品,可在修改大型列表时提供更好的性能。

    ...

    以下是 blist 渐近优于内置列表的一些用例:

    Use Case                                      blist              list
    --------------------------------------------------------------------------
    Insertion into or removal from a list         O(log n)           O(n)
    Taking slices of lists                        O(log n)           O(n)
    Making shallow copies of lists                O(1)               O(n)
    Changing slices of lists                      O(log n + log k)   O(n+k)
    Multiplying a list to make a sparse list      O(log k)           O(kn)
    Maintain a sorted lists with bisect.insort    O(log**2 n)        O(n)
    

    这里有一些性能数据 --> http://stutzbachenterprises.com/performance-blist

    【讨论】:

    【解决方案3】:

    这有点小技巧,但您也可以使用来自SortedContainers 模块的SortedListWithKey 数据类型。您只希望键返回一个常量,以便您可以按照自己喜欢的方式对元素进行排序。试试这个:

    from sortedcontainers import SortedListWithKey
    
    class FastDeque(SortedListWithKey):
        def __init__(self, iterable=None, **kwargs):
            super(FastDeque, self).__init__(iterable, key=lambda val: 0, **kwargs)
    
    items = FastDeque('abcde')
    
    print items
    # FastDeque(['a', 'b', 'c', 'd', 'e'], key=<function <lambda> at 0x1089bc8c0>, load=1000)
    
    del items[0]
    items.insert(0, 'f')
    
    print list(items)
    # ['f', 'b', 'c', 'd', 'e']
    

    FastDeque 将有效地支持快速随机访问和删除。 SortedContainers 模块的其他好处:纯 Python、快如 C 的实现、100% 的单元测试覆盖率、数小时的压力测试。

    【讨论】: