# negative stride list slices

Peter Otten __peter__ at web.de
Wed Sep 1 20:51:04 CEST 2004

```David Abrahams wrote:

> Can anyone explain the logic behind the behavior of list slicing with
> negative strides?  For example:
>
>   >>> print range(10)[:-3:-1]
>   [9,8]
>
> I found this result very surprising, and would just like to see the
> rules written down somewhere.

Well, here is my attempt to emulate the algorithm. The trick seems to be to
substitute the start/stop parameters with 0 or length-1 depending on the
sign of step.

# no warranties!
def indices(length, start, stop, step):
if step is None:
step = 1
if step < 0:
if start is None:
start = length-1
elif start < 0:
start += length

if stop is None:
stop = -1
elif stop < 0:
stop += length
else:
if start is None:
start = 0
elif start < 0:
start += length

if stop is None:
stop = length
elif stop < 0:
stop += length

if start > stop:
while start > stop:
yield start
start += step
else:
while start < stop:
yield start
start += step

assert list(indices(10, None, -3, -1)) == range(10)[:-3:-1]
assert list(indices(10, None, -3, -2)) == range(10)[:-3:-2]
assert list(indices(10, 9, -3, -2)) == range(10)[9:-3:-2]
assert list(indices(10, None, None, None)) == range(10)[::]
assert list(indices(10, None, 5, 2)) == range(10)[:5:2]

I have to admit (late but better than never) that Raymond Hettinger's new
builtin reversed() has some merits:

>>> list(reversed(range(10)[-2:])) == range(10)[:-3:-1]
True

Peter

```