Looping backwards in python and getting the index

Viewed 105

There are multiple ways to loop back in python For example we have

arr=[5,6,8]
for i in range(len(arr)-1, -1, -1):
  print(i," ",arr[i])

which gives

2   8
1   6
0   5

I can solve what I need with that, but I am curious. There is another way to loop back which is

for im in arr[::-1]:
  print(im) 

Looks nice, right? This gives

8
6
5

My question is, using this second method is there a way to get not only the element but also the index? (the 2,1,0)

7 Answers

There's a builtin for that: reversed. This might be more readable and intuitive than using a range or slice with negative step.

For just the index, you can pass the range to reversed directly:

arr = list("ABC")

for i in reversed(range(len(arr))):
    print(i, arr[i])                   
# 2 C
# 1 B
# 0 A

For index and element, you have to collect the enumerate iterator into a list before reversing:

for i, x in reversed(list(enumerate(arr))):
    print(i, x)                
# 2 C
# 1 B
# 0 A

use the builtin method reversed

arr = [5, 6, 8]
for i in reversed(range(0,len(arr))):
    print(i,arr[i])

Here's a way using reversed() and zip() that should be memory efficient:


arr = [5, 6, 8]

for idx, elem in zip(reversed(range(len(arr))),
                     reversed(arr)
                     ):
    print(idx, elem)

Output:

2 8
1 6
0 5
for idx, elem in list(enumerate(arr))[::-1]:
    print(idx, elem)

This uses enumerate to keep elements with their specific index. Then we convert it to list and reverse (enumerate result is not reversible without converting). No need to keep track of any order (like subtracting) manually

You can also just reverse the forward range:

for idx in range(len(arr))[::-1]:
   print(idx, arr[idx])

Python actually reverses range in a smart way, without converting it to a list, so it works even for big stuff:

>>> range(10)[::-1]
range(9, -1, -1)

This means that range(len(arr))[::-1] will work in exactly the same way, with exactly the same speed, as your range(len(arr)-1, -1, -1) while looking nice!

i = len(arr) - 1
for im in arr[::-1]:
    print(i, " ", im)
    i -= 1

You can use enumerate and subtract from the initial length:

arr=[5,6,8]
for i,im in enumerate(arr[::-1]):
    print(len(arr)-i-1, im)

output:

2 8
1 6
0 5

The normal way to iterate with an index is with enumerate. One can use this to index the other way by subtracting the index from the length of the sequence:

In [51]: arr = [5, 6, 8]
    ...: for i, n in enumerate(arr):
    ...:     print(i, n)
    ...: 
0 5
1 6
2 8

In [52]: for i, n in enumerate(reversed(arr)):
    ...:     print(len(arr) - i - 1, n)
    ...: 
2 8
1 6
0 5

Note that reversed doesn't create a new list in memory and is preferable to [::-1] if just iterating.

Related