web-dev-qa-db-ja.com

Pythonで「逆」リストを作成する最良の方法は?

Pythonでは、アイテムが他のリストのものと同じであるが、逆の順序で新しいリストを作成する最良の方法は何ですか? (既存のリストをその場で変更したくありません。)

私に起こった1つの解決策は次のとおりです。

new_list = list(reversed(old_list))

old_listを複製してから、その場所で複製を逆にすることもできます。

new_list = list(old_list) # or `new_list = old_list[:]`
new_list.reverse()

見落としているより良いオプションはありますか?そうでない場合、上記のアプローチの1つを他のアプローチよりも使用する説得力のある理由(効率など)がありますか?

83
davidchambers
newlist = oldlist[::-1]

[::-1]スライス(妻のアンナは「火星のスマイリー」と呼ぶのが好きです;-)は、シーケンス全体を-1のステップで、つまり逆にスライスします。すべてのシーケンスで機能します。

これは(andあなたが言及した選択肢)が「浅いコピー」と同等であることに注意してください。逆のリストの項目にもあります。逆も同様です。それを避ける必要がある場合は、copy.deepcopy(常に潜在的にコストのかかる操作)、この場合は.reverse、唯一の良いオプションです。

194
Alex Martelli

では、 timeit にしましょう。 ヒント:アレックスの[::-1]は最速です:)

$ p -m timeit "ol = [1, 2, 3]; nl = list(reversed(ol))"
100000 loops, best of 3: 2.34 usec per loop

$ p -m timeit "ol = [1, 2, 3]; nl = list(ol); nl.reverse();"
1000000 loops, best of 3: 0.686 usec per loop

$ p -m timeit "ol = [1, 2, 3]; nl = ol[::-1];"
1000000 loops, best of 3: 0.569 usec per loop

$ p -m timeit "ol = [1, 2, 3]; nl = [i for i in reversed(ol)];"
1000000 loops, best of 3: 1.48 usec per loop


$ p -m timeit "ol = [1, 2, 3]*1000; nl = list(reversed(ol))"
10000 loops, best of 3: 44.7 usec per loop

$ p -m timeit "ol = [1, 2, 3]*1000; nl = list(ol); nl.reverse();"
10000 loops, best of 3: 27.2 usec per loop

$ p -m timeit "ol = [1, 2, 3]*1000; nl = ol[::-1];"
10000 loops, best of 3: 24.3 usec per loop

$ p -m timeit "ol = [1, 2, 3]*1000; nl = [i for i in reversed(ol)];"
10000 loops, best of 3: 155 usec per loop

更新:inspectorG4dgetによって提案されたリストcompメソッドを追加しました。結果をそのまま伝えます。

53
Sam Dolan

調整

しばしば不必要なlist()変換なしで 'reversed'のパフォーマンスを示すsdolanによるtimeit計算のベースラインベンチマーク/調整を提供する価値があります。このlist()操作は、ランタイムに26個のusecsを追加し、イテレーターが受け入れられない場合にのみ必要です。

結果:

_reversed(lst) -- 11.2 usecs

list(reversed(lst)) -- 37.1 usecs

lst[::-1] -- 23.6 usecs
_

計算:

_# I ran this set of 100000 and came up with 11.2, twice:
python -m timeit "ol = [1, 2, 3]*1000; nl = reversed(ol)"
100000 loops, best of 3: 11.2 usec per loop

# This shows the overhead of list()
python -m timeit "ol = [1, 2, 3]*1000; nl = list(reversed(ol))"
10000 loops, best of 3: 37.1 usec per loop

# This is the result for reverse via -1 step slices
python -m timeit "ol = [1, 2, 3]*1000;nl = ol[::-1]"
10000 loops, best of 3: 23.6 usec per loop
_

結論:

これらのテストの結論は、reversed()は12.4 usecsのスライス_[::-1]_よりも高速です

7
mekarpeles