この質問に対する答えは、反復ごとに追加されるリスト/タプルのサイズが小さいことにかかっていることも指摘しておく価値があります。より大きなリストの場合、extend が明らかに優れています (また、リストとタプルは違いがありません)。mgilsonのanswerから始めて、2 項目ではなく 600 項目のコレクションの動作を確認しました: append を 600 回呼び出すextend()
と、手動で定義されたリスト/タプル (つまり[v,v,v,v,v,v,v...]
)を使用する場合の 8 倍の時間がかかります。
42.4969689846
5.45146393776
5.38034892082
この 5 秒の大部分は、実際にはリスト/タプルの作成です。電話の前に準備することでtimeit
、延長の時間が短縮されます
1.42491698265
0.657584905624
それぞれリストとタプル。
より現実的な (そして公平な) ケースとして、関数呼び出し内でデータを動的に生成できます。
import timeit
def append_loop(foo, reps):
for i in range(reps):
foo.append(i)
def append_comp(foo, reps):
[foo.append(i) for i in range(reps)]
def extend_lst(foo, reps):
foo.extend([i for i in range(reps)])
def extend_tup(foo, reps):
foo.extend((i for i in range(reps)))
repetitions = 600
print timeit.timeit('append_loop([], repetitions)', setup='from __main__ import append_loop, repetitions')
print timeit.timeit('append_comp([], repetitions)', setup='from __main__ import append_comp, repetitions')
print timeit.timeit('extend_lst([], repetitions)', setup='from __main__ import extend_lst, repetitions')
print timeit.timeit('extend_tup([], repetitions)', setup='from __main__ import extend_tup, repetitions')
(Append は、for ループとリスト内包表記の両方を介して実装され、ループの 2 つの方法の間の効率の違いを取り除きます。)
タイミングは次のとおりです。
53.8211231232
57.1711571217
19.8829259872
28.5986201763
ご覧のとおり、リスト内包表記による拡張は、追加よりも 2 倍以上高速です。また、タプル内包表記はリスト内包表記よりも著しく遅く見え、append_comp
不必要なリスト作成オーバーヘッドを導入するだけです。