# How can I iterate over a list backward?

### Question

In the context of this code challenge, how can I iterate over a list backward?

There are a few ways that you can iterate over a list backward.

One way is by utilizing the `range()` method, with a negative `step` value, so that the index decreases by 1 per element, essentially going backward in the list. The `start` index must begin at the last index of the list, and the `end` index would have to be offset by 1 to the first index, because it is exclusive. This will look something like the following,

``````for i in range(len(list)-1, -1, -1):
...
``````

Another way to iterate over a list backward is to utilize list slicing, with a negative step. This will return a new list of elements in reverse order.

``````for i in list[::-1]:
...
``````
16 Likes

Extra Study

Consider the classic game of the distant past, Reversii where we are given a random list of numbers and have to put them in order using only flips from the right hand side. We wonâ€™t get into that level of difficulty, yet, but we can flip the entire list as a starting point. Letâ€™s take a list of 10 items and flip itâ€¦

``````>>> x = list(range(10))
>>> a, b = x[0], x[-1]
>>> x[0], x[-1] = b, a
>>> x
[9, 1, 2, 3, 4, 5, 6, 7, 8, 0]
>>> a, b = x[1], x[-2]
>>> x[1], x[-2] = b, a
>>> x
[9, 8, 2, 3, 4, 5, 6, 7, 1, 0]
>>> a, b = x[2], x[-3]
>>> x[2], x[-3] = b, a
>>> x
[9, 8, 7, 3, 4, 5, 6, 2, 1, 0]
>>> a, b = x[3], x[-4]
>>> x[3], x[-4] = b, a
>>> x
[9, 8, 7, 6, 4, 5, 3, 2, 1, 0]
>>> a, b = x[4], x[-5]
>>> x[4], x[-5] = b, a
>>> x
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
``````

Now letâ€™s take a list of 9 items and flip itâ€¦

``````>>> x = list(range(1, 10))
>>> a, b = x[0], x[-1]
>>> x[0], x[-1] = b, a
>>> x
[9, 2, 3, 4, 5, 6, 7, 8, 1]
>>> a, b = x[1], x[-2]
>>> x[1], x[-2] = b, a
>>> x
[9, 8, 3, 4, 5, 6, 7, 2, 1]
>>> a, b = x[2], x[-3]
>>> x[2], x[-3] = b, a
>>> x
[9, 8, 7, 4, 5, 6, 3, 2, 1]
>>> a, b = x[3], x[-4]
>>> x[3], x[-4] = b, a
>>> x
[9, 8, 7, 6, 5, 4, 3, 2, 1]
>>>
``````

See any pattern there? This is suggestive of an algorithm. All we need is to understand a breaking condition to set it in motion. Note the condition on `while` belowâ€¦

``````>>> x = list(range(10))
>>> i = 0
>>> while i + 1 <= len(x) // 2:
a, b = x[i], x[-(i+1)]
x[i], x[-(i+1)] = b, a
i += 1

>>> x
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> x = list(range(1, 10))
>>> i = 0
>>> while i + 1 <= len(x) // 2:
a, b = x[i], x[-(i+1)]
x[i], x[-(i+1)] = b, a
i += 1

>>> x
[9, 8, 7, 6, 5, 4, 3, 2, 1]
>>>
``````

Any hint as to how we would use `i` in the Reversii plot?

As noted, this is for extra study when one has competed the course. Bookmark it and return later to explore this concept. It wonâ€™t come up in the course but will surely have piqued your interest. See you on the flip-flop.

We can intuit this into a utility function now that we have the mechanics and contraints we needâ€¦

``````>>> def reverse(x, i=0):
while i + 1 <= len(x) // 2:
a, b = x[i], x[-(i+1)]
x[i], x[-(i+1)] = b, a
i += 1
return x

>>> reverse(list(range(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> reverse(list(range(1, 10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1]
>>>
``````

Just to note, weâ€™re close, but this is not Reversii.

Extra Study, piled onâ€¦

To make our function less vulnerable to stray inputsâ€¦

``````>>> def reverse(x, i=0):
try:
while i + 1 <= len(x) // 2:
x[-i - 1], x[i] = x[i], x[-i - 1]
i += 1
return x
except:
return x
``````
``````>>> reverse('a string')
'a string'
>>> reverse(1)
1
>>> reverse({'one': 1})
{'one': 1}
>>> reverse(list(range(1, 10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> reverse(list(range(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>>
``````

Whatâ€™s more we can deal with one exception, a `str` parameterâ€¦

``````>>> def reverse(x, i=0):
try:
while i + 1 <= len(x) // 2:
x[-i - 1], x[i] = x[i], x[-i - 1]
i += 1
return x
except:
if isinstance(x, str):
return ''.join(reverse(list(x)))
else:
return x

>>> reverse('a string')
'gnirts a'
>>>
``````
22 Likes

Can some one please explain why this code does not work? Solution use a =! condition I have used == condition

``````  for x in range(len(lst1)):
if lst1[x] == lst2[len(lst2)-1-x]:
return True
return False
``````
2 Likes

Because it returns True without going through the whole of either list.

Not finding a match would give cause to return False, and exit the function.

To return True, we must have matched every character of both strings. The loop needs to complete before we can draw that conclusion.

8 Likes

Hello,

can someone please explain me 2 things?

a)Why is the second number in range for going backward -1, and not (+)1?

I thought the second number in a range of 3 numbers canâ€™t be lesser than 1, since in that case it would represent an element with index 0, no? If the second number is -1 doesnâ€™t it represent an element with index -2?

b)What are the 2 colons in the example given for going backward using list slicing?

`for i in list [ : : -1 ]`

Thank you.

3 Likes

First off, did you write an algorithm to reverse the list without slicing? Itâ€™s important that you learn a couple of ways to do this before jumping on the wagon of Python built-in methods.

As far as the slice goes,

``````[ start index : end index : stride length ]
``````

A negative stride length indicates moving from right to left in the list.

python - How to explain the reverse of a sequence by slice notation a[::-1] - Stack Overflow

8 Likes

Thank you sir, I see thereâ€™s a lot explained in the link you provided, I definitely have to take some time to go through it.

1 Like

for this specific lesson, why wouldnâ€™t the following solution work? itâ€™s saying itâ€™s not the correct solution, but it does what it is asking, right? am i missing something?

``````def reversed_list(lst1, lst2):
return lst1[:] == lst2[::-1]
``````
4 Likes

Slicing is a viable solution, but may not be what the SCT is expecting. Perhaps create an algorithm that compares iteratively rather than using the slice method.

2 Likes

Is there an inbuilt function to reverse a list?

Yes there is,

`````` list.reverse()
``````

as well as the slice,

`````` list[::-1]
``````

In the learning stages we will often focus on naive, iterative approaches.

2 Likes

I donâ€™t understand what this particular part of the code is doing:

lst2[len(lst2) - 1 - index]

Up until this point of the course, I havenâ€™t seen this taught and how it translates to reversing the list. The solution to the code for the exercise is below, but I donâ€™t get that part of it.

def reversed_list(lst1, lst2):
for index in range(len(lst1)):
if lst1[index] != lst2[len(lst2) - 1 - index]:
return False
return True
#Uncomment the lines below when your function is done
print(reversed_list([1, 2, 3], [3, 2, 1]))
print(reversed_list([1, 5, 3], [3, 2, 1]))

3 Likes

It is accessing the second list with an index that is the same distance from the right end as `index` is from the left.

1 Like

Ok, so would:

lst2[len(lst2) - 1]

mean start from the right?

1 Like

Yes, that would be the last index from the left, and first index from the right, same as, `lst2[-1]`.

1 Like

def reversed_list(lst1,lst2):
if lst1 == lst2.reverse():
return True
else:
return False

print(reversed_list([1, 2, 3], [3, 2, 1]))
print(reversed_list([1, 5, 3], [3, 2, 1]))

this returns #false false?

I know you need to do list(reversed(lst2)) but I canâ€™t seem to get it to work here?

`````` lst2.reverse()
return lst1 == lst2
``````
2 Likes

Can you explain why it doesnâ€™t work in the if statement?

1 Like

`list.reverse()` returns None. It just reverses the list!

``````def reversed_list(lst1,lst2):
lst2.reverse()
if lst1 == lst2:
return True
else:
return False

print(reversed_list([1, 2, 3], [3, 2, 1]))
print(reversed_list([1, 5, 3], [3, 2, 1]))

# Output:
True
False
``````
1 Like

Thank you, it seems to be a pattern that many methods .sort, .reverse, etc do not return anything, is there something to that?