Pythonのenumerateでハマった

Pythonではリストなどにループをかける場合、普通にこんな感じで書くわけだ。

>>> a = [0,1,2,3,4,5]
>>> for x in a:
...     print x,
... 
0 1 2 3 4 5

インデックスが必要な場合はenumerateを使う。

>>> a = [0,1,2,3,4,5]
>>> for i,x in enumerate(a):
...     print "a[%d]=%d"%(i,x)
... 
a[0]=0
a[1]=1
a[2]=2
a[3]=3
a[4]=4
a[5]=5

これを用いて一つ前の要素との差を求めたかった。a[1]とa[0]の差は1といった感じで、a=[0,1,1,1,1,1]になって欲しい。0番目は何もしない。この何もしないというのを、リストのインデックス1番目から始めれば良いと考えたのがマズかった。

>>> a = [0,1,2,3,4,5]
>>> b = [x for x in a]
>>> for i,x in enumerate(a[1:]):
...     a[i] -= b[i-1]
... 
>>> a
[-5, 1, 1, 1, 1, 5]

期待する値ではない。考えれば当然だがa[1:]というのはリスト[1,2,3,4,5]をである。iにも0から入っていく。これをaのインデックス1から渡しているので、iには1から入っていくと思い込んでいた。結構ハマってしまった。書き直すとすればif文で条件を分けるか、iに1を加えるか。if文の方がいいかな。

>>> a = [0,1,2,3,4,5]
>>> b = [x for x in a]
>>> for i,x in enumerate(a):
...     if i != 0:
...             a[i] -= b[i-1]
...  
>>> a
[0, 1, 1, 1, 1, 1]