リストの部分リストを得るとき、つぎのようにします。
a = range(5) # [0, 1, 2, 3, 4] a[1:3] # [1, 2]
range(1, 3)に対応しています。同様にステップ幅も指定できます。
a[1:4:2] # [1, 3] a[3:0:-1] # [3, 2, 1]
これもrange(1, 4, 2)、range(3, 0, -1)に対応しています。
最初と次の項を省略すると最初からと最後までと解釈されます。
a[2:] # [2, 3, 4] a[3::-1] # [3, 2, 1, 0]
両方省略することもできます。
a[:] # [0, 1, 2, 3, 4] a[::-1] # [4, 3, 2, 1, 0]
それぞれ、copyとreverseになっています。
さて、ここからが本題です。次のようなコードを組みたいとします。リストからインデックスkとlの間を取り出します。例えば、[0, 1, 4, 9, 16]で1, 3なら[1, 4, 9]、3, 1なら[9, 4, 1]となります。
k < lとそれ以外の場合わけが要ります。
if k < l: return a[k:l+1] else: return a[k:l-1:-1]
しかし、これには罠があります。l = 0のとき、
a[2:0-1:-1] # []
-1は末尾の要素を指すため、a[2:4:-1]と同じになってしまうからです。そのためさらに場合わけが必要です。
if k < l: return a[k:l+1] elif l == 0: return a[k::-1] else: return a[k:l-1:-1]
しかし、これよりもreverseする方が短く書けます。
if k < l: return a[k:l+1] else: return a[l:k+1][::-1]