简体   繁体   中英

reversing list using slicing [ : 0:-1] in Python

I am confused in the list slicing in Python.

For a list

L=[0,1,2,3,4,5,6,7,8,9,10]

I wanted to reverse the list and could get the answer by

L[::-1] 

getting [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] .

However, when I tried

L[10:0:-1]

I got [10,9,8,7,6,5,4,3,2,1] without 0 . Neither L[10:1:-1] nor L[10:-1:-1] give the answer.

On the other hand, L[200::-1] , L[10:-12:-1] gives correct answer, though L[200] , L[-12] is out of bounds.

I would like to understand the underlying logic of Python for this case. Thank you.

Let's take a list for example,

a = [1, 2, 3, 4, 4, 5, 6, 9]

If you try to slice it using positive indices,

newa = a[1:5] 

This will result in

newa = [2, 3, 4, 4] 

This is because, in the above case slicing occurs like this, a[inclusive : exclusive], first index is included and slicing begins from this index, and end just one index before the index(5), exclusive(remember). This is just the way how list slicing works.

To get last two values of the list a,

newa = [6 : ]

Here, the index starts from 6(inclusive) and ends till end of the list.

If you are keen in using negative indexing in lists as Python offers to ease up indexing, know once and for all the inclusive and exclusive thing about slicing.

For same example above, to get last two numbers of the list using negative index, what we do is,

newa = a[-2 : ]

In the case of positive indexing, the index begins at 0 while for negative indexing, the index is at -1, -2 and so on. So in the above example, starting from second last number in the list, slice till the end of the list, is what is understood.

Now, to reverse the list, one could do,

print a.reverse()
[9, 6, 5, 4, 4, 3, 2, 1]

In slicing way, list can be reversed by giving it a [start, end, step] like mentioned above, but I would like to clarify it further.

 r = a[2: : -1]

This will make a new list starting with number from index 2, and till the end of the list, but since the step is -1, we decrease from index 2, till we reach 0. Hence we come up with a reversed list of first three numbers as below:

r = [3, 2, 1]

Also, to get a whole of the list as reversed,

r = a[len(a): : -1]

This will start from 8, the length of the list, but in indices terms which begins from 0, we have 0 till 8 indices, so starting from 8th indices, it goes on decreasing in steps of -1, till the end of the list. The result is as:

[9, 6, 5, 4, 4, 3, 2, 1]

I personally prefer to use this for reversing the list.

For the Python list slicing syntax, list[start:end:step] will get a sliced list with items starting with list[start] , but list[end] is excluded. As a result, in your case, L[10:0:-1] will exclude L[0] , ie , 0, and L[10::-1] will work as you expect.

When the start or end is a negative number, it means it counts from the end of the list. So list[-1] will get the last item in the list. In your case, L[10:-1:-1] is equivalent to L[10:10:-1] . So L[10:-1:-1] will get [] .

 >>> L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 >>> L[1:3]
 [1, 2]

index 3 is excluding

>>> L[0:10:1]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

index 10 is excluding, and if you want to select all,you should use:

>>>L[0:11:1]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

but you can not get L[11] ,it will be throw IndexError ,because you only have 11 elements,the max index is 10, the reason L[0:11:1] will not out of bound because this slice will not access to L[11] only from index 0 to 10.

>>> L[10:0:-1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

-1 is a step of slice reversely,also 0 is excluding,

and L[10:-1:-1] is equivalent to L[10:10:-1] ,because the first -1 means the last index of L

>>> L[10:-12:-1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

index -11 is equivalent to index 0 , index -12 is equivalent to index before 0

The above answers correctly explain what happens when list slices are used. However, I would like to touch upon the final part of the question - how does L[200::-1] or L[10:-12:-1] work even though both 200 and 12 are out of bounds of the array?

You can simply understand it this way - When slices are used to extract elements from a sequence, python ensures that the indices used within the slice are within the the length of the sequence. Hence in your case, when you specify L[200::-1] , what happens internally is that Python checks that the length of the sequence L is only 11 and hence treats the above statement as L[10::-1] instead. Similar argument applies to L[10:-12:-1] .

This link provides a good insight into section-slices. Typically at the end of this page there is a description and an example on how to implement sequences that support extended slicing. To quote:

slice objects now have a method indices(length) which, given the length of a sequence, returns a (start, stop, step) tuple that can be passed directly to range(). indices() handles omitted and out-of-bounds indices in a manner consistent with regular slices (and this innocuous phrase hides a welter of confusing details!).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM