Reversing a list using slice notation

PythonListSyntaxSlice

Python Problem Overview


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?

Python Solutions


Solution 1 - Python

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:
https://stackoverflow.com/questions/509211/good-primer-for-python-slice-notation

Solution 2 - Python

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 - Python

> ...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 - Python

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 - Python

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

foo[-1:-7:-1]

Solution 6 - Python

This is a very good question, and, in my opinion, none of the above answers really answer the question being asked. Partly because an intellectually honest answer may reveal a weakness of Python type system. And the same weakness exists in some other languages.

A more intellectually honest answer would probably be: Python slicing does not generalize well.

Precisely, one can traverse a collection in one direction with collection[begin:end] but collection[end:begin:-1] does not work. It does not work because the first index is 0 but the "index before the first index" is not -1. Thus, collection[end:-1:-1] does not evaluate to what we would legitimately expect.

The [first to include : first to exclude : step] explanation is flawed. If "first to exclude" is the one before the first element, you cannot express it the same way you would in the case that you wanted to include that same first element.

In conclusion, you're not crazy to expect generality, it is just not there.

Solution 7 - Python

Use

>>>foo[::-1]

This displays the reverse of the list from the end element to the start,

Solution 8 - Python

Complement. to reverse step by 2:

A = [1,2,2,3,3]
n = len(A)
res = [None] * n
mid = n//2 + 1 if n%2 == 1 else n//2

res[0::2] = A[0:mid][::-1]
res[1::2] = A[0:mid][::-1]
print(res)

[2, 3, 2, 3, 1]

Solution 9 - Python

formalizing the answer from andrew-clark a little bit more:

Suppose the list v and v[n1:n2:n3] slice. n1 is initial position, n2 is final position and n3 is step

Let's write some pseucode in a Python way:

n3 = 1  if (n3 is missing) else n3
if n3==0:
   raise exception # error, undefined step

First part: n3 positive

if n3>0:
   slice direction is from left to right, the most common direction         
   
   n1 is left slice position in `v` 
   if n1 is missing: 
      n1 = 0   # initial position
   if n1>=0:
      n1 is a normal position
   else: 
     (-n1-1) is the position in the list from right to left 

   n2 is right slice position in `v` 
   if n2 is missing: 
      n2 = len(x)  # after final position
   if n2>=0:
      n2 is a normal final position (exclusive)
   else: 
      -n2-1 é the final position in the list from right to left 
       (exclusive)

Second part: n3 negative

else: 
  slice direction is from right to left (inverse direction)

  n1 is right slice position in `v` 
  if n1 is missing: 
     n1 = -1   # final position is last position in the list.
  if n1>=0:
     n1 is a normal position
  else: 
     (-n1-1) is the position in the list from right to left 

  n2 is  left slice position in `v` 
  if n2 is missing: 
     n2 = -len(x)-1   # before 1st character  (exclusive)
  if n2>=0:
     n2 is a normal final position (exclusive)
  else: 
     -n2-1 is the ending position in the list from right to left 
     (exclusive)

Now the original problema: How to reverse a list with slice notation?

L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(L(::-1)) # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

Why?
n1 is missing and n3<0 => n1=0
n2 is missing and n3<0 => n2 = -len(x)-1

So L(::-1) == L(-1:-11:-1)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser737079View Question on Stackoverflow
Solution 1 - PythonAndrew ClarkView Answer on Stackoverflow
Solution 2 - PythonCaptain LeptonView Answer on Stackoverflow
Solution 3 - PythonFred NurkView Answer on Stackoverflow
Solution 4 - PythonEmreuView Answer on Stackoverflow
Solution 5 - PythonmyQwilView Answer on Stackoverflow
Solution 6 - PythonfokiView Answer on Stackoverflow
Solution 7 - PythonAshmita DuttaView Answer on Stackoverflow
Solution 8 - PythonCharlie 木匠View Answer on Stackoverflow
Solution 9 - PythonPaulo BuchsbaumView Answer on Stackoverflow