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種類ぐらいあるみたい。
- rangeの第3引数に-1を指定
- reversed(list)を使う
- スライスを使う
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]