问题
Suppose we have this list:
>>> a = [x for x in range(10)]
>>> print(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Separately, both ways to slice work as expected:
>>> a[3:8]
[3, 4, 5, 6, 7]
>>> a[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
But, when combined:
>>> a[3:8:-1]
[]
I would expect it to be [7, 6, 5 ,4, 3]
or perhaps [6, 5, 4, 3, 2]
(if reversing happened first).
It is also interesting to consider what happens when either start
or stop
parameters are not passed:
>>> a[:5:-1]
[9, 8, 7, 6]
This is almost what I would expect, only its one item short. Tested this with numpy
and it seems to behave in the same way.
Whats going on here?
回答1:
With
a[3:8:-1]
The start and stop positions of the slice aren't adjusted based on the step. With a negative step, you're having it go backwards from 3, but there are no elements with indices in the range 3 to 8 counting back from 3, so you get an empty list.
You need to set the start and stop accordingly:
a[8:3:-1]
Which will count back from 8 to 4.
回答2:
a[3:8:-1]
instructs python to start from 3 and go to 8 by steps of -1
This creates an empty list: it's not possible to reach 8 from 3 by adding -1
(just like list(range(3,8,-1))
which gives an empty list too)
When you do a[:5:-1]
then start is the default start, which python sets to "end of list" so it "works"
Same as when you do a[::-1]
the start & stop are the default ones, and python understands that they're from end to start (else this notation wouldn't be useable)
回答3:
This behavior is explained in the documentation.
The slice of s from i to j is defined as the sequence of items with index k such that i <= k < j. If i or j is greater than len(s), use len(s). If i is omitted or None, use 0. If j is omitted or None, use len(s). If i is greater than or equal to j, the slice is empty.
The slice of s from i to j with step k.... stopping when j is reached (but never including j). When k is positive, i and j are reduced to len(s) if they are greater. When k is negative, i and j are reduced to len(s) - 1 if they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k).
来源:https://stackoverflow.com/questions/59147480/strange-behavior-with-python-slicing