How can I slice a list till end with negative indexes
I learned that Python lists can also be traversed using negative index, so I tried to slice/sublist a list using negative index, but I cannot slice it till end.
My list is:
areas = ["hallway", 11.25, "kitchen", 18.0, "living room", 20.0, "bedroom", 10.75, "bathroom", 9.50]
Knowing that slicing syntax is [start:end]
and end index is not calculated, I did upstairs = areas[-4:0]
but this doesn't give me last element of the list.
areas[-4:0]
translates to areas[len(areas) - 4: 0]
, which is effectively slicing from a higher index to a lower. Semantically, this doesn't make much sense, and the result is an empty list.
You're instead looking for:
>>> areas[-4:]
['bedroom', 10.75, 'bathroom', 9.5]
When the last index is not specified, it is assumed you slice till the very end.
As an aside, specifying 0
would make sense when you slice in reverse. For example,
>>> areas[-4:0:-1]
['bedroom', 20.0, 'living room', 18.0, 'kitchen', 11.25]
Happens to be perfectly valid. Here, you slice from len(areas) - 4
down to (but not including) index 0
, in reverse.
Firstly, I wonder how you could access a slice by using areas[-4:0], it should return an empty list.
https://repl.it/repls/CarefreeOilyLine
You can use areas[-4:] which should return
> areas[-4:]
=> ['bedroom', 10.75, 'bathroom', 9.5]
Actually, you can think -4
as len(areas) - 4
like
> areas[len(areas)-4:]
=> ['bedroom', 10.75, 'bathroom', 9.5]
> areas[0:-4]
=> ['hallway', 11.25, 'kitchen', 18.0, 'living room', 20.0]
> areas[0:len(areas)-4]
=> ['hallway', 11.25, 'kitchen', 18.0, 'living room', 20.0]
> areas[0:6]
=> ['hallway', 11.25, 'kitchen', 18.0, 'living room', 20.0]
and 0 cannot represent 0 and len(areas) - 0 at the same time. Of course, it works with areas[-4:len(areas)]
.
0
is not a negative number which is why it will always refer to the left-most element.
If you are hardcoding a single slice that is no problem, because you can just leave out the right boundary as in areas[-4:]
But what to do if your boundaries are computed at runtime?
>>> for left in range(-8, -3, 2):
... right = left + 4
... print(areas[left:right])
...
['kitchen', 18.0, 'living room', 20.0]
['living room', 20.0, 'bedroom', 10.75]
[]
As you found out this doesn't work.
You'll often hear to just add the length of the list:
>>> for left in range(-8, -3, 2):
... right = left + 4
... print(areas[len(areas)+left:len(areas)+right])
...
['kitchen', 18.0, 'living room', 20.0]
['living room', 20.0, 'bedroom', 10.75]
['bedroom', 10.75, 'bathroom', 9.5]
But that doesn't always work either:
>>> for left in range(-12, -3, 2):
... right = left + 4
... print(areas[len(areas)+left:len(areas)+right])
...
[]
['hallway', 11.25, 'kitchen', 18.0]
['kitchen', 18.0, 'living room', 20.0]
['living room', 20.0, 'bedroom', 10.75]
['bedroom', 10.75, 'bathroom', 9.5]
So here is an idiom that works in a few more cases:
>>> for left in range(-12, -3, 2):
... right = left + 4
... print(areas[left or None:right or None])
...
['hallway', 11.25]
['hallway', 11.25, 'kitchen', 18.0]
['kitchen', 18.0, 'living room', 20.0]
['living room', 20.0, 'bedroom', 10.75]
['bedroom', 10.75, 'bathroom', 9.5]
But you can break this as well:
>>> for left in range(-12, -1, 2):
... right = left + 4
... print(areas[left or None:right or None])
...
['hallway', 11.25]
['hallway', 11.25, 'kitchen', 18.0]
['kitchen', 18.0, 'living room', 20.0]
['living room', 20.0, 'bedroom', 10.75]
['bedroom', 10.75, 'bathroom', 9.5]
[]
What do we learn from this? Negative indices are ok for hard coding but require some care when used dynamically. In a program, it may be safest to avoid negative semantics and consistently use max(0, index)
.
上一篇: 在JavaScript中修剪字符串?
下一篇: 我怎样才能切分列表,直到消极索引结束