Reversing a list using slice notation

94,978

Solution 1

Slice notation in short:

[ <first element to include> : <first element to exclude> : <step> ]

If you want to include the first element when reversing a list, leave the middle element empty, like this:

foo[::-1]

You can also find some good information about Python slices in general here:
Explain Python's slice notation

Solution 2

If you are having trouble remembering slice notation, you could try doing the Hokey Cokey:

[In: Out: Shake it all about]

[First element to include: First element to leave out: The step to use]

YMMV

Solution 3

This answer might be a little outdated, but it could be helpful for someone who stuck with same problem. You can get reverse list with an arbitrary end - up to 0 index, applying second in-place slice like this:

>>> L = list(range(10))
>>> L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> (start_ex, end) = (7, 0)
>>> L[end:start_ex][::-1]
[6, 5, 4, 3, 2, 1, 0]

Solution 4

...why foo[6:0:-1] doesn't print the entire list?

Because the middle value is the exclusive, rather than inclusive, stop value. The interval notation is [start, stop).

This is exactly how [x]range works:

>>> range(6, 0, -1)
[6, 5, 4, 3, 2, 1]

Those are the indices that get included in your resulting list, and they don't include 0 for the first item.

>>> range(6, -1, -1)
[6, 5, 4, 3, 2, 1, 0]

Another way to look at it is:

>>> L = ['red', 'white', 'blue', 1, 2, 3]
>>> L[0:6:1]
['red', 'white', 'blue', 1, 2, 3]
>>> len(L)
6
>>> L[5]
3
>>> L[6]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

The index 6 is beyond (one-past, precisely) the valid indices for L, so excluding it from the range as the excluded stop value:

>>> range(0, 6, 1)
[0, 1, 2, 3, 4, 5]

Still gives you indices for each item in the list.

Solution 5

You can get it to work if you use a negative stop value. Try this:

foo[-1:-7:-1]
Share:
94,978
Admin
Author by

Admin

Updated on December 11, 2021

Comments

  • Admin
    Admin over 2 years

    in the following example:

    foo = ['red', 'white', 'blue', 1, 2, 3]
    

    where: foo[0:6:1] will print all elements in foo. However, foo[6:0:-1] will omit the 1st or 0th element.

    >>> foo[6:0:-1]
    [3, 2, 1, 'blue', 'white']
    

    I understand that I can use foo.reverse() or foo[::-1] to print the list in reverse, but I'm trying to understand why foo[6:0:-1] doesn't print the entire list?

  • Shrey Shivam
    Shrey Shivam about 13 years
    This: [ <first element to include> : <first element to exclude> : <step> ] is the clearest explanation of the slice syntax I've seen. Calling it "first element to exclude" really makes it obvious what's going on.
  • huggie
    huggie about 10 years
    What about negative slicing with negative steps? I still don't get it.
  • Andrew Clark
    Andrew Clark about 10 years
    When you use a negative index as either <first element to include> or <first element to exclude> it is indexing from the back of the list, so -1 is the last element, -2 is the second to last element, etc. So for example, x[-1:-4:-1] would get the last three elements of x in reversed order. So you might interpret this as "moving backwards take each element (-1 step) from the last element in the list (-1 <first element to include>) up until but not including the fourth element from the end (-4 <first element to include>)".
  • Cloud
    Cloud almost 6 years
    range can do it but slice can't do it, because -1 is the last element. So l=[1, 2, 3], l[2:-1:-1] == [].
  • djvg
    djvg over 5 years
    When reversing (i.e. if <step> is -1), it helps me to think <first element to include, moving from right to left>. So, to get the n "leftmost" elements from a list in reverse order: foo[n-1::-1]. To get the n "rightmost" elements in reverse order: foo[-1:-n-1:-1].
  • Tom Zych
    Tom Zych over 5 years
    This is actually pretty useful, because you can use the same syntax for all cases. You don’t have to treat 0 as a special case.
  • BallpointBen
    BallpointBen over 4 years
    How do you make the first element to exclude "the element before foo[0]"?
  • Dwayne Robinson
    Dwayne Robinson over 4 years
    This makes more sense than Python/numpy's default behavior for negative slicing, because normally ones wants to slice and/or reverse an image or tensor aligned to a given edge, whereas Python/numpy lose that last row/column of the data o_O.
  • nyholku
    nyholku almost 3 years
    So far clearest explanation in the whole web I've seen. However I think it could be slightly improved. "(-n1-1) is the position in the list from right to left" is correct but I bet most people think this in term of "normal" array indexes from 0..size-1 so (-n1-1) would become ((size-1)-(-n1-1))) i.e.( size+n1)
  • testing_22
    testing_22 almost 3 years
    The notation is very useful. The key if it's -1 is to remember it will get elements from back to front<-- when outputting, so you start index must be greater than the end index (even if those indexes are negative numbers)