Today I Learned

A Hashrocket project

range() v slice()

A range is not a slice and a slice is not a range. But they look the same.

slice(1, 10)
# slice(1, 10, None)
range(1, 10)
# range(1, 10)

They both take step as a third argument.

slice(1, 10, 3)
# slice(1, 10, 3)
range(1, 10, 3)
# range(1, 10, 3)

But one is iterable and the other is not.

list(slice(1, 10))
# TypeError: 'slice' object is not iterable
list(range(1, 10))
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

One can be used as a list indices, one cannot.

[1, 2, 3, 4, 5][range(1, 2)]
# TypeError: list indices must be integers or slices, not range
>>> [1, 2, 3, 4, 5][slice(1, 2)]
# [2]

They both conform to the start, stop, step interface.

s = slice(1, 10)
s.start, s.stop, s.step
# (1, 10, None)
r = range(1, 10)
r.start, r.stop, r.step
# (1, 10, 1)

You can slice a range but you can’t range a slice.

range(1, 10)[slice(2, 8)]
# range(3, 9)
slice(1, 10)[range(2, 8)]
# TypeError: 'slice' object is not subscriptable