Reversing a list using slice notation
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?
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:
...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 4:
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 5:
You can get it to work if you use a negative stop value. Try this:
foo[-1:-7:-1]