问题:简短的python列表之前的惯用语法是什么?
list.append()是添加到列表末尾的明显选择。这是有关失踪人员的合理解释list.prepend()。假设我的清单很短并且对性能的关注可以忽略不计,
list.insert(0, x)要么
list[0:0] = [x]惯用的?
回答 0
该s.insert(0, x)形式是最常见的。
但是,无论何时看到它,都可能是时候考虑使用collections.deque而不是列表了。
回答 1
如果可以使用功能性方法,则以下内容很清楚
new_list = [x] + your_list当然,你还没有插入x到your_list,而你已经创建了一个新的列表xpreprended它。
回答 2
简短的python列表之前的惯用语法是什么?
通常,您不想在Python中重复地放在列表之前。
如果它很短,并且您没有做很多…那么就可以了。
list.insert
该list.insert可以采用这种方式。
list.insert(0, x)但这是无效的,因为在Python中,a list是一个指针数组,并且Python现在必须获取列表中的每个指针并将其向下移动一个,以将指向对象的指针插入第一个插槽中,因此,这实际上仅是有效的根据您的要求列出较短的清单。
这是实现该功能的CPython源代码的一个片段-如您所见,我们从数组的末尾开始,每次插入将所有内容向下移动一位:
for (i = n; --i >= where; )
    items[i+1] = items[i];如果您希望容器/列表能够高效地添加元素,则需要一个链表。Python有一个双向链表,可以在开头和结尾快速插入-称为a deque。
deque.appendleft
A collections.deque具有列表的许多方法。list.sort是一个exceptions,deque绝对不能完全用Liskov代替list。
>>> set(dir(list)) - set(dir(deque))
{'sort'}在deque还有一个appendleft方法(以及popleft)。它deque是一个双端队列和一个双向链接的列表-不管长度如何,总是需要花费相同的时间来准备某些东西。在大O表示法中,列表的O(1)与O(n)时间。这是用法:
>>> import collections
>>> d = collections.deque('1234')
>>> d
deque(['1', '2', '3', '4'])
>>> d.appendleft('0')
>>> d
deque(['0', '1', '2', '3', '4'])deque.extendleft
与此相关的还有双端队列的extendleft方法,该方法反复进行:
>>> from collections import deque
>>> d2 = deque('def')
>>> d2.extendleft('cba')
>>> d2
deque(['a', 'b', 'c', 'd', 'e', 'f'])请注意,每个元素将一次添加一个,从而有效地颠倒了它们的顺序。
listvs的表现deque
首先,我们设置一些迭代的前缀:
import timeit
from collections import deque
def list_insert_0():
    l = []
    for i in range(20):
        l.insert(0, i)
def list_slice_insert():
    l = []
    for i in range(20):
        l[:0] = [i]      # semantically same as list.insert(0, i)
def list_add():
    l = []
    for i in range(20):
        l = [i] + l      # caveat: new list each time
def deque_appendleft():
    d = deque()
    for i in range(20):
        d.appendleft(i)  # semantically same as list.insert(0, i)
def deque_extendleft():
    d = deque()
    d.extendleft(range(20)) # semantically same as deque_appendleft above和性能:
>>> min(timeit.repeat(list_insert_0))
2.8267281929729506
>>> min(timeit.repeat(list_slice_insert))
2.5210217320127413
>>> min(timeit.repeat(list_add))
2.0641671380144544
>>> min(timeit.repeat(deque_appendleft))
1.5863927800091915
>>> min(timeit.repeat(deque_extendleft))
0.5352169770048931双端队列更快。随着列表的增加,我希望双端队列的性能更好。如果您可以使用双端队列,则extendleft可能会以这种方式获得最佳性能。
回答 3
如果有人像我一样发现这个问题,这是我对建议方法的性能测试:
Python 2.7.8
In [1]: %timeit ([1]*1000000).insert(0, 0)
100 loops, best of 3: 4.62 ms per loop
In [2]: %timeit ([1]*1000000)[0:0] = [0]
100 loops, best of 3: 4.55 ms per loop
In [3]: %timeit [0] + [1]*1000000
100 loops, best of 3: 8.04 ms per loop如您所见,insert切片分配几乎是显式添加速度的两倍,并且结果非常接近。正如Raymond Hettinger指出的那样,这insert是更常见的选择,我个人更喜欢这种方式优先列出。

