为什么 Python 的列表没有 shift/unshift 方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34210969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 14:37:03  来源:igfitidea点击:

Why Python's list does not have shift/unshift methods?

pythonlist

提问by nowox

I am wondering why the default listin Python does not have any shift, unshiftmethods. Maybe there is an obvious reason for it like the way the lists are ordered in memory.

我想知道为什么listPython 中的默认值没有任何shift,unshift方法。也许有一个明显的原因,比如列表在内存中的排序方式。

So currently, I know that I can use appendto add an item at the end of a list and popto remove an element from the end. However, I can only use list concatenation to imitate the behavior of a missing shiftor unshiftmethod.

所以目前,我知道我可以用来append在列表的末尾添加一个项目并从末尾pop删除一个元素。但是,我只能使用列表连接来模仿缺失shiftunshift方法的行为。

>>> a = [1,2,3,4,5]
>>> a = [0] + a  # Unshift / Push
>>> a
[0,1,2,3,4,5]
>>> a = a[1:]  # Shift / UnPush
>>> a
[1,2,3,4,5]

Did I miss something?

我错过了什么?

采纳答案by wim

Python lists were optimized for fast fixed-length operations and incur O(n) memory movement costs for pop(0)and insert(0, v)operations which change both the size and position of the underlying data representation. Actually, the "list" datatype in CPython works differently as to what many other languages might call a list (e.g. a linked-list) - it is implemented more similarly to what other languages might call an array, though there are some differences here too.

Python列表被用于快速固定长度的操作进行了优化和招致O(n)的存储器移动成本pop(0)insert(0, v)操作,这些操作的改变的大小和底层数据表示的位置。实际上,CPython 中的“列表”数据类型与许多其他语言可能称为列表(例如链接列表)的工作方式不同 - 它的实现与其他语言可能称为数组的内容更相似,尽管这里也有一些差异.

You may be interested instead in collections.deque, which is a list-like container with fast appends and pops on either end.

您可能对 感兴趣collections.deque,它是一个类似列表的容器,两端都有快速追加和弹出。

Deques support thread-safe, memory efficient appends and pops from either side of the deque with approximately the same O(1) performance in either direction.

双端队列支持线程安全、内存高效的追加和从双端队列的任一侧弹出,在任一方向上的 O(1) 性能大致相同。

The missing methods you appear to be asking about are provided under the names appendleftand popleft:

您似乎在询问的缺失方法在名称下提供,appendleft并且popleft

appendleft(x)

Add x to the left side of the deque.

popleft()

Remove and return an element from the left side of the deque. If no elements are present, raises an IndexError.

追加左( x)

将 x 添加到双端队列的左侧。

弹出左键()

从双端队列的左侧移除并返回一个元素。如果不存在元素,则引发 IndexError。

Of course there is a trade-off, and indexing or inserting/removing near the middleof the deque is slow. In fact deque.insert(index, object)wasn't even possible before Python 3.5, you would need to rotate, insert/pop, and rotate back. You also lose slicing, so if you needed that you'll have to write something annoying with e.g. itertools.isliceinstead.

当然有一个权衡,在双端队列中间附近建立索引或插入/删除很慢。事实上deque.insert(index, object)在 Python 3.5 之前甚至是不可能的,你需要旋转、插入/弹出和旋转回来。你也失去了切片,所以如果你需要,你必须写一些烦人的东西,例如itertools.islice

For further discussion of the advantages and disadvantages of dequevs listdata structures, see How are deques in Python implemented, and when are they worse than lists?

要进一步讨论dequevslist数据结构的优缺点,请参阅Python 中的双端队列是如何实现的,它们何时比列表更糟糕?