回答:
s.insert(0, x)
フォームは、最も一般的です。
しかし、それを目にしたときはいつでも、リストの代わりにcollections.dequeを使用することを検討するときかもしれません。
あなたが機能的な方法で行くことができれば、以下はかなり明確です
new_list = [x] + your_list
もちろん、あなたはに挿入x
していません。むしろ、それに先行your_list
する新しいリストをx
作成しました。
短いpythonリストの前に付ける慣用的な構文は何ですか?
通常、Pythonのリストの先頭に繰り返し追加することは望ましくありません。
それが短くて、あなたがそれをあまりやっていないなら...そしてそれから。
list.insert
list.insert
この方法を使用することができます。
list.insert(0, x)
しかし、これは非効率的です。Pythonでは、a list
はポインタの配列であり、Pythonはリスト内のすべてのポインタを取得して1つ下に移動し、最初のスロットにオブジェクトへのポインタを挿入する必要があるため、これは本当に効率的ですあなたが尋ねるように、かなり短いリストのために。
これが実装されているCPythonソースのスニペットを次に示します。ご覧のとおり、配列の最後から開始して、挿入ごとに1つずつ下に移動します。
for (i = n; --i >= where; )
items[i+1] = items[i];
先頭に要素を追加するのに効率的なコンテナ/リストが必要な場合は、リンクリストが必要です。Pythonには二重にリンクされたリストがあり、最初と最後にすばやく挿入できます。これはと呼ばれますdeque
。
deque.appendleft
Aにcollections.deque
はリストのメソッドの多くがあります。list.sort
は例外であり、deque
完全にLiskovをの代わりに使用できるわけではありませんlist
。
>>> set(dir(list)) - set(dir(deque))
{'sort'}
にdeque
もappendleft
メソッドがあります(およびpopleft
)。deque
ダブルエンドキューと二重リンクリストである-に関係なく長さは、それは常にpreprendの何かに同じ時間がかかります。大きなO表記では、リストのO(1)時間に対するO(1)時間。使い方は次のとおりです。
>>> import collections
>>> d = collections.deque('1234')
>>> d
deque(['1', '2', '3', '4'])
>>> d.appendleft('0')
>>> d
deque(['0', '1', '2', '3', '4'])
deque.extendleft
また、dequeのextendleft
メソッドも関連しています。
>>> from collections import deque
>>> d2 = deque('def')
>>> d2.extendleft('cba')
>>> d2
deque(['a', 'b', 'c', 'd', 'e', 'f'])
各要素は一度に1つずつ追加されるので、実際には順序が逆になることに注意してください。
list
対のパフォーマンス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
dequeははるかに高速です。リストが長くなるにつれ、dequeのパフォーマンスがさらに向上することを期待しています。deque's extendleft
を使用できる場合は、おそらくその方法で最高のパフォーマンスが得られます。
私のように誰かがこの質問を見つけた場合、提案された方法のパフォーマンステストを次に示します。
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
、スライスの割り当ては明示的な追加のほぼ2倍の速さで、結果は非常に近いです。以下のようレイモンドヘッティンガーが指摘はinsert
、より一般的なオプションであると私は、個人的にリストに付加するこの方法を好みます。
.insert
と[0:0] = [0]
仕事インプレース、彼らはまだ再割り当てバッファ全体に持っています。