LoginSignup
42
32

More than 5 years have passed since last update.

Pythonのsort()とreverse()について

Last updated at Posted at 2016-09-06

PythonのListには、sort()やreverse()など、順序を変更する関数が用意されていますが、これらを使う場合には仕様を理解して使わないと困ったことになります。

その困ったことに先日ハマりましたので残しておきます。

返り値がNone

たとえば、ほかの関数と同じように、

print([1,3,8,7,4].sort())

と書いても、Noneが表示されます

同じように、

print([1,3,8,7,4].reverse())

でも結果は同じです。

Pythonのドキュメントを読む

sort()

とりあえずPythonのドキュメントを読むと、このような記述がありました。

このメソッドは、大きなシーケンスをソートするときの容量の節約のため、シーケンスをインプレースに変化させます。副作用としてこの演算が行われることをユーザに気づかせるために、これはソートしたシーケンスを返しません。
http://docs.python.jp/3/library/stdtypes.html#list.sort

つまり、sort()は破壊的変更を行うだけで、ソートされたリストを返すわけではないということです。

ドキュメントには続けて

新しいリストインスタンスを明示的に要求するには sorted() を使ってください

とあります。

つまり、

l = [1,3,8,7,4]
l.sort()
print(l)

と書くか、

print(sorted([1,3,8,7,4]))

と書く必要があります

reverse()

reverse()も、ドキュメントを読んでみると、

reverse() メソッドは、大きなシーケンスを反転するときの容量の節約のため、シーケンスをインプレースに変化させます。副作用としてこの演算が行われることをユーザに気づかせるために、これは反転したシーケンスを返しません
http://docs.python.jp/3/library/stdtypes.html#mutable-sequence-types

とあります。つまりsort()と同じように一度変数に入れて破壊的変更をした後、printする必要があります。

すると、一つ疑問が浮かんできます。

反転済みのリストを返すreversed()は無いの?と。

結論から言えば、reversed()関数自体は存在します。

しかし、ソート済みのリストを返すsorted()と違い、reversed()が返すのは与えたリストの逆順のイテレータということです。

そのため、イテレータからリストを生成する必要があるため、

print([i for i in reversed([1,3,8,7,4])])

と、する必要があります。

しかし、リストを反転させるだけであれば、もっと簡単に書けます。

print([1,3,8,7,4][::-1])

[1,3,8,7,4][::-1]の[::-1]はスライスといい、詳しいことは省略しますが、リストから一部を抽出して新しいリストを作れる機能です。

コロン区切りで3つの値を指定でき(省略することも可能)、1つ目は抽出を開始する地点、2つ目は抽出を終了する地点、3つめは抽出する間隔です。

今回は、間隔は-1なので、1ずつインクリメントして抽出(=すべて抽出)し、更にマイナスが付いているのでリストの後ろから抽出を開始します。

なので、逆順のリストが帰ってきます。

リストの反転方法の使い分けとしては、

省メモリに処理したい → reverse()

反転したリストを作るついでに各値に何か処理を加えたい(2倍にするなど) → reversed()

とりあえず反転させたい → スライス

で使い分ければいいと思います。

まとめ

挙動がよくわからないならドキュメントを読もう。

42
32
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
32