頑張らないために頑張る

ゆるく頑張ります

Pythonのリストを逆順に並べ替える方法

Posted at — Apr 27, 2022

小ネタです

Pythonにおいて、リストの要素を逆順に並び変えるにはいろいろ方法はあります。

結論から言ってしまうと、リスト・文字列・タプルと汎用的に使えるスライスで処理するのが一番楽です。しかも、もともとのデータを破壊しない(新しいオブジェクトを作る)ので安心。

スライス

>>> hoge = [1, 2, 3]
>>> hoge[::-1]
[3, 2, 1]
>>> hoge
[1, 2, 3]

上記はスライスによる逆順処理です。スライスは[start:end:step]の形で指定しますが、startendが指定されない場合は、全要素が対象になります。全要素を対象としつつstep-1とすると、最後の要素を最初に参照します。あとは最後から最初に1件ずつさかのぼって参照されるため、逆順に並べ替えられるというわけです。新しいオブジェクトを返すので、もともとのリストはそのままなのもポイント高い。

reverse()

>>> hoge = [1, 2, 3]
>>> print(hoge.reverse())
None
>>> hoge
[3, 2, 1]
>>> hoge.reverse()
>>> hoge
[1, 2, 3]
>>> hoge = (1, 2, 3)
>>> hoge.reverse()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'reverse'
>>> hoge = 'foobarbaz'
>>> hoge.reverse()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'reverse'

リストのみ有効ですが、逆順処理するreverse()メソッドがあります。これは、もともとのリストを直接変更するので、戻り値はNoneであることに注意。実行された時点で、リストの内容が書き換わります。もともとのデータを書き換えるためミュータブルなリストでのみ可能で、文字列やタプルなどでは利用できません。

reversed()

前述のreverse()メソッドと似ていますが、こっちは組み込み関数のreversed()です。

>>> hoge
[1, 2, 3]
>>> reversed(hoge)
<list_reverseiterator object at 0x7fb748484670>
>>> list(reversed(hoge))
[3, 2, 1]
>>> hoge
[1, 2, 3]
>>> hoge = (1, 2, 3)
>>> tuple(reversed(hoge))
(3, 2, 1)
>>> hoge
(1, 2, 3)
>>> hoge = 'foobarbaz'
>>> reversed(hoge)
<reversed object at 0x7fb7485ff9d0>
>>> list(reversed(hoge))
['z', 'a', 'b', 'r', 'a', 'b', 'o', 'o', 'f']
>>> ''.join(list(reversed(hoge)))
'zabraboof'
>>> hoge
'foobarbaz'

組み込み関数のreversed()を利用すると、戻り値はイテレータです。そのままでは利用できない(for文などでは使える)ので、上記ではlist()を使ってリストに直しています。これはもともとのデータを書き換えず、新しいオブジェクトを作成してくれます。リストだけでなく、文字列やタプルにも利用できるのはメソッドと比較すると大きいメリット。

ただ、文字列やタプルにも使えるとは言いましたが、いかんせん戻り値がイテレータなのでやっぱり直接的に利用できないのが玉にキズ。よって、tuple()でタプルに直したり、join()で一度リストにしたものを結合し文字列に直す必要があります。

>>> hoge = [1, 2, 3]
>>> fuga = (4, 5, 6)
>>> piyo = 'foobarbaz'
>>> hoge[::-1]
[3, 2, 1]
>>> fuga[::-1]
(6, 5, 4)
>>> piyo[::-1]
'zabraboof'
>>> hoge
[1, 2, 3]
>>> fuga
(4, 5, 6)
>>> piyo
'foobarbaz'

なお、スライスを利用すればリストやタプルなどの形式に関係なく処理可能。しかも、もともとのデータを変更しません。もうこれでいいのでは、って気がします。ってか、これでいいよねぇ。

reference

  1. array.reverse
  2. reversed
comments powered by Disqus