Python は柔軟な言語であり、同じ単純なタスクを実行するためにいくつかの方法があるのが普通です。
アプローチの選択は、時間や空間の複雑さ、または単に個人的な好みに依存することができます。
Pythonのデータ構造は非常に便利で直感的であり、その組み込み機能は簡単に扱えます。
この記事では、Pythonでリストを逆引きする方法について見ていきます。
Pythonのリストは、異種混在(異なる型を含むことができる)配列のような構造で、メモリ内のオブジェクトへの参照を格納します。
リストを操作する場合、新しく変更されたリストを作成するか、元のリストをインプレースで変更することができます。
これらの違いについては、記事を進めていく中で確認していきましょう。
reverse() メソッドを使ったリストの逆引き
Pythonはデータ構造のデータを操作するための強力なビルトインメソッドライブラリを持っています。
リストを反転させるために、組み込みの reverse()
メソッドを利用することができます。
注意: reverse()
メソッドは、リストをインプレースで反転させます。
インプレースでリストを反転させるということは、新しい反転リストを作成するのではなく、元のリストを変更することを意味します。
このため、結果のオブジェクトを新しい変数に代入することはできません。
また、元のリストをメモリ上に残しておきたい場合は、反転する前にそれをコピーしなければなりません。
my_list = [1, 2, 3, 4]
my_list.reverse()
print(my_list) # Output: [4, 3, 2, 1]
new_list = my_list.reverse()
print(new_list) # Output: None
戻り値はありません。
リストはインプレースで反転されます。
しかし、反転する前にcopy()
することができます。
list_1 = [1, 2, 3, 4]
list_2 = list_1.copy()
list_1.reverse()
print('Reversed list: ', list_1)
print('Saved original list: ', list_2)
この結果は
Reversed list: [4, 3, 2, 1]
Saved original list: [1, 2, 3, 4]
スライス記法によるリストの逆引き
スライス記法は、リスト、文字列、タプル、NumPyの配列など、様々なコレクションやコレクションベースのオブジェクトの一部をスライスして再生することを可能にします。
リストをスライスすると、そのリストの一部が返され、すべての step
番目の要素が含まれます。
my_list = [1, 2, 3, 4, 5, 6]
# list[start:end:step]
segment_1 = my_list[1:5:1]
segment_2 = my_list[1:5:2]
print(segment_1)
print(segment_2)
この結果は
[2, 3, 4, 5]
[2, 4]
startと
endの引数を省略することで、コレクション全体を含めることができます。
また、step` に負の数を設定することで、コレクションを逆順に繰り返し処理することができます。
original_list = [1, 2, 3, 4, 5, 6]
reversed_list = original_list[::-1]
print('Original list: ', original_list)
print('Reversed list: ', reversed_list)
という結果になります。
Original list: [1, 2, 3, 4, 5, 6]
Reversed list: [6, 5, 4, 3, 2, 1]
スライス記法は元のリストには全く影響を与えないので、操作後も original_list
は同じままです。
slice() メソッドによるリストの逆順化
slice()メソッドは、
start,
end,
stepという全く同じパラメータを受け取り、スライス記法とほぼ同じ処理を行います。
ただし、startと
endの引数を省略する代わりに、
None` を渡すことができます。
戻り値の型は Slice
オブジェクトで、これを使用してコレクションを内容に応じてスライスすることができる。
スライスするコレクションでは呼び出されない。
生成後に Slice
オブジェクトを渡すことで、多くの異なるコレクションに対して再利用可能で呼び出し可能な単一のオブジェクトを作成することが可能になる。
内部的にはスライス記法にトランスパイルされているので、最終的な結果は同じになります。
original_list = [1, 2, 3, 4, 5, 6]
slice_obj = slice(None, None, -1)
print('slice_obj type:', type(slice_obj))
print('Reversed list:', original_list[slice_obj])
という結果になります。
slice_obj type: <class 'slice'=""
Reversed list: [6, 5, 4, 3, 2, 1]
For Loopを使ったリストの逆引き
元のリストをそのままにしておきたいかどうかに応じて、元のリストから pop()
要素を抜き出して新しいリストに追加したり、単に逆順に追加したりすることができます。
pop()はコレクションから最後の要素を取り除き、それを返します。
これとappend()` メソッドを組み合わせることで、削除した要素を新しいリストに直接追加することができます。
original_list = [1, 2, 3, 4]
reversed_list = []
for i in range(len(original_list)):
reversed_list.append(original_list.pop())
print(reversed_list) # Output: [4, 3, 2, 1]
また、リストを逆引きして -1
番目のインデックス (非含有) まで繰り返し、そのリストで見た各要素を追加することもできます。
range()メソッドは 3 つの引数 -
start,
end,
step` を受け取ることができ、前と同じように使用することができます。
original_list = [1, 2, 3, 4]
reversed_list = []
for i in range(len(original_list)-1, -1, -1):
reversed_list.append(original_list[i])
print(reversed_list) # Output: [4, 3, 2, 1]
reversed() メソッドによるリストの反転
負のステップで反復処理した後に元のリストの各要素にアクセスするのは少し冗長なので、 reversed()
メソッドが追加されました。
これにより、反転のロジックを手動で実装するのがずっと簡単になり、独自の工夫を加えたくなった場合にも対応できるようになります。
reversed()` メソッドはイテレータを返し、コレクションを反転した順序で反復処理します – そして、これらの要素を新しいリストに簡単に追加することができます。
original_list = [1, 2, 3, 4]
new_list = []
for i in reversed(original_list):
new_list.append(i)
print(new_list) # Output: [4, 3, 2, 1]
print(original_list) # Output: [1, 2, 3, 4] --> Original hasn't changed
結論
Pythonでリストを反転させるには、新しい反転リストが必要か、インプレース反転リストが必要か、また、ロジックを処理してほしいか、反転中に追加の操作やひねりを柔軟に加えたいかによって、いくつかの方法があります。
このチュートリアルでは、これらのシナリオについて、それぞれの違いを強調しながら説明しています。
</class