In Python 3.9, it is not possible to use a range object to index a list.
Indeed running the following code, the second print will return an error stating "TypeError: list indices must be integers or slices, not range".
x = [1, 2, 3] s = slice(3) r = range(3) print(x[s]) # ok print(x[r]) # error
Why is this? Couldn’t the Python interpreter just convert the range to a slice under the hood, and use that for indexing?
Is this because of some fundamental reason, or is just something the developer did not implement (yet?)?
Interestingly, it is indeed possible to index numpy arrays using range!
range are subtly different things, even though both use a
start, stop, step triplet. If Python were to silently use one in place of the other, it could lead to subtle bugs.
To see the difference directly, one can indeed look at
numpy where the two cause different indexing:
>>> arr = np.array([0, 1, 2, 3, 4]) >>> arr[slice(1, -1)] array([1, 2, 3]) >>> arr[range(1, -1)] array(, dtype=int64)
The result is different because
range have different meaning for negative numbers.
rangerepresents a part of the number line of integers. This extends to negative numbers.
slicerepresents a part of the ordinal numbers/indices of sequences.1 This wraps negative numbers back to positive numbers.
Or put simpler, the meaning of a
slice depends on the size of a sequence whereas a
range does not. Thus, accidentally using one in place of the other would be wrong.
1 Technically, a
slice represents any concept of
start, stop, step. The standard sequence types interpret this as numerical indices. It is also possible for a
slice to represent the edges of a graph, for example.
Answered By – MisterMiyagi
Answer Checked By – Willingham (AngularFixing Volunteer)