にたまごほうれん草アーカイブ

はてなダイアリーで書いてた「にたまごほうれん草」という日記のアーカイブです。現在は「にたまごほうれん草ブログ」を運営中です。

range()で生成したリストの逆順を得る

for文でrangeをインデックスにして使うときにちょっとハマったのでメモ。(Python 2.5.5)

ハマってたこと

リストを逆順にするreverse()メソッドを使おうとして、

a = range(10)
a.reverse()
#=> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

となるのに、

a = range(10).reverse()
#=> None

となってしまう。そのため、for文で使いにくくて困っていた。

解決方法

結局、やり方としては3種類ぐらいあるみたい。

  1. rangeの第3引数に-1を指定
  2. reversed(list)を使う
  3. スライスを使う
rangeの第3引数に-1を指定

rangeの第3引数は生成する配列の数値の間隔。
ただし、range(10)の逆順を得ようとすると、第1,2引数もそれぞれ1引かないといけないので使いづらい。

range(10, 0, -1)
#=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
range(9, -1, -1)
#=> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(list)を使う

reversedはリストの逆順のイテレータを返す関数。
なので、リストそのものを得たい場合はさらにlist()を噛ませる。

list(reversed(range(10)))
#=> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
スライスを使う

入門的なスライスの説明にはあまり書かれていなかったが、リストや文字列などのシーケンスをスライスするときに、コロンで区切った3番目にstepを指定することができる。
1,2番目に何も指定せずstepに-1を指定すると、シーケンスの逆順(のコピー)を取り出すことができる。

range(10)[::-1]
#=> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

さいごに

見やすさとしては(2)だけど、書きやすさでは(3)かな。
実行時のパフォーマンスにまで目をやる余裕はまだないけど、pythonではスライスを使い慣れておくとよさそうな気がするので、(3)の方法を使っていくことになると思う。
それにしても、range(10).reverse()という記述ができないということは、Pythonユーザには当たり前に認知されていることなのだろうか…