Traverse a list in reverse order in Python
Question:
How do I traverse a list in reverse order in Python? So I can start from collection[len(collection)-1]
and end in collection[0]
.
I also want to be able to access the loop index.
Answers:
Use the built-in reversed()
function:
>>> a = ["foo", "bar", "baz"]
>>> for i in reversed(a):
... print(i)
...
baz
bar
foo
To also access the original index, use enumerate()
on your list before passing it to reversed()
:
>>> for i, e in reversed(list(enumerate(a))):
... print(i, e)
...
2 baz
1 bar
0 foo
Since enumerate()
returns a generator and generators can’t be reversed, you need to convert it to a list
first.
Use list.reverse()
and then iterate as you normally would.
the reverse function comes in handy here:
myArray = [1,2,3,4]
myArray.reverse()
for x in myArray:
print x
You can do:
for item in my_list[::-1]:
print item
(Or whatever you want to do in the for loop.)
The [::-1]
slice reverses the list in the for loop (but won’t actually modify your list “permanently”).
If you need the loop index, and don’t want to traverse the entire list twice, or use extra memory, I’d write a generator.
def reverse_enum(L):
for index in reversed(xrange(len(L))):
yield index, L[index]
L = ['foo', 'bar', 'bas']
for index, item in reverse_enum(L):
print index, item
It can be done like this:
for i in range(len(collection)-1, -1, -1):
print collection[i]
# print(collection[i]) for python 3. +
So your guess was pretty close 🙂 A little awkward but it’s basically saying: start with 1 less than len(collection)
, keep going until you get to just before -1, by steps of -1.
Fyi, the help
function is very useful as it lets you view the docs for something from the Python console, eg:
help(range)
The reversed
builtin function is handy:
for item in reversed(sequence):
The documentation for reversed explains its limitations.
For the cases where I have to walk a sequence in reverse along with the index (e.g. for in-place modifications changing the sequence length), I have this function defined an my codeutil module:
from six.moves import zip as izip, range as xrange
def reversed_enumerate(sequence):
return izip(
reversed(xrange(len(sequence))),
reversed(sequence),
)
This one avoids creating a copy of the sequence. Obviously, the reversed
limitations still apply.
The other answers are good, but if you want to do as
List comprehension style
collection = ['a','b','c']
[item for item in reversed( collection ) ]
How about without recreating a new list, you can do by indexing:
>>> foo = ['1a','2b','3c','4d']
>>> for i in range(len(foo)):
... print foo[-(i+1)]
...
4d
3c
2b
1a
>>>
OR
>>> length = len(foo)
>>> for i in range(length):
... print foo[length-i-1]
...
4d
3c
2b
1a
>>>
def reverse(spam):
k = []
for i in spam:
k.insert(0,i)
return "".join(k)
I like the one-liner generator approach:
((i, sequence[i]) for i in reversed(xrange(len(sequence))))
>>> l = ["a","b","c","d"]
>>> l.reverse()
>>> l
['d', 'c', 'b', 'a']
OR
>>> print l[::-1]
['d', 'c', 'b', 'a']
To use negative indices: start at -1 and step back by -1 at each iteration.
>>> a = ["foo", "bar", "baz"]
>>> for i in range(-1, -1*(len(a)+1), -1):
... print i, a[i]
...
-1 baz
-2 bar
-3 foo
You can also use a while
loop:
i = len(collection)-1
while i>=0:
value = collection[i]
index = i
i-=1
An approach with no imports:
for i in range(1,len(arr)+1):
print(arr[-i])
Time complexity O(n) and space complexity O(1).
An approach that creates a new list in memory, be careful with large lists:
for i in arr[::-1]:
print(i)
Time complexity O(n) and space complexity O(n).
for what ever it’s worth you can do it like this too. very simple.
a = [1, 2, 3, 4, 5, 6, 7]
for x in xrange(len(a)):
x += 1
print a[-x]
You can use a negative index in an ordinary for loop:
>>> collection = ["ham", "spam", "eggs", "baked beans"]
>>> for i in range(1, len(collection) + 1):
... print(collection[-i])
...
baked beans
eggs
spam
ham
To access the index as though you were iterating forward over a reversed copy of the collection, use i - 1
:
>>> for i in range(1, len(collection) + 1):
... print(i-1, collection[-i])
...
0 baked beans
1 eggs
2 spam
3 ham
To access the original, un-reversed index, use len(collection) - i
:
>>> for i in range(1, len(collection) + 1):
... print(len(collection)-i, collection[-i])
...
3 baked beans
2 eggs
1 spam
0 ham
A simple way :
n = int(input())
arr = list(map(int, input().split()))
for i in reversed(range(0, n)):
print("%d %d" %(i, arr[i]))
Also, you could use either “range” or “count” functions.
As follows:
a = ["foo", "bar", "baz"]
for i in range(len(a)-1, -1, -1):
print(i, a[i])
3 baz
2 bar
1 foo
You could also use “count” from itertools as following:
a = ["foo", "bar", "baz"]
from itertools import count, takewhile
def larger_than_0(x):
return x > 0
for x in takewhile(larger_than_0, count(3, -1)):
print(x, a[x-1])
3 baz
2 bar
1 foo
In python 3, list creates a copy, so reversed(list(enumerate(collection))
could be inefficient, generating yet an other list is not optimized away.
If collection is a list for sure, then it may be best to hide the complexity behind an iterator
def reversed_enumerate(collection: list):
for i in range(len(collection)-1, -1, -1):
yield i, collection[i]
so, the cleanest is:
for i, elem in reversed_enumerate(['foo', 'bar', 'baz']):
print(i, elem)
input_list = ['foo','bar','baz']
for i in range(-1,-len(input_list)-1,-1)
print(input_list[i])
i think this one is also simple way to do it… read from end and keep decrementing till the length of list, since we never execute the “end” index hence added -1 also
If you need the index and your list is small, the most readable way is to do reversed(list(enumerate(your_list)))
like the accepted answer says. But this creates a copy of your list, so if your list is taking up a large portion of your memory you’ll have to subtract the index returned by enumerate(reversed())
from len()-1
.
If you just need to do it once:
a = ['b', 'd', 'c', 'a']
for index, value in enumerate(reversed(a)):
index = len(a)-1 - index
do_something(index, value)
or if you need to do this multiple times you should use a generator:
def enumerate_reversed(lyst):
for index, value in enumerate(reversed(lyst)):
index = len(lyst)-1 - index
yield index, value
for index, value in enumerate_reversed(a):
do_something(index, value)
Assuming task is to find last element that satisfies some condition in a list (i.e. first when looking backwards), I’m getting following numbers.
Python 2:
>>> min(timeit.repeat('for i in xrange(len(xs)-1,-1,-1):n if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))
4.6937971115112305
>>> min(timeit.repeat('for i in reversed(xrange(0, len(xs))):n if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))
4.809093952178955
>>> min(timeit.repeat('for i, x in enumerate(reversed(xs), 1):n if 128 == x: break', setup='xs, n = range(256), 0', repeat=8))
4.931743860244751
>>> min(timeit.repeat('for i, x in enumerate(xs[::-1]):n if 128 == x: break', setup='xs, n = range(256), 0', repeat=8))
5.548468112945557
>>> min(timeit.repeat('for i in xrange(len(xs), 0, -1):n if 128 == xs[i - 1]: break', setup='xs, n = range(256), 0', repeat=8))
6.286104917526245
>>> min(timeit.repeat('i = len(xs)nwhile 0 < i:n i -= 1n if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))
8.384078979492188
So, the ugliest option xrange(len(xs)-1,-1,-1)
is the fastest.
Python 3 (different machine):
>>> timeit.timeit('for i in range(len(xs)-1,-1,-1):n if 128 == xs[i]: break', setup='xs, n = range(256), 0', number=400000)
4.48873088900001
>>> timeit.timeit('for i in reversed(range(0, len(xs))):n if 128 == xs[i]: break', setup='xs, n = range(256), 0', number=400000)
4.540959084000008
>>> timeit.timeit('for i, x in enumerate(reversed(xs), 1):n if 128 == x: break', setup='xs, n = range(256), 0', number=400000)
1.9069805409999958
>>> timeit.timeit('for i, x in enumerate(xs[::-1]):n if 128 == x: break', setup='xs, n = range(256), 0', number=400000)
2.960720073999994
>>> timeit.timeit('for i in range(len(xs), 0, -1):n if 128 == xs[i - 1]: break', setup='xs, n = range(256), 0', number=400000)
5.316207007999992
>>> timeit.timeit('i = len(xs)nwhile 0 < i:n i -= 1n if 128 == xs[i]: break', setup='xs, n = range(256), 0', number=400000)
5.802550058999998
Here, enumerate(reversed(xs), 1)
is the fastest.
If you don’t mind the index being negative, you can do:
>>> a = ["foo", "bar", "baz"]
>>> for i in range(len(a)):
... print(~i, a[~i]))
-1 baz
-2 bar
-3 foo
I think the most elegant way is to transform enumerate
and reversed
using the following generator
(-(ri+1), val) for ri, val in enumerate(reversed(foo))
which generates a the reverse of the enumerate
iterator
Example:
foo = [1,2,3]
bar = [3,6,9]
[
bar[i] - val
for i, val in ((-(ri+1), val) for ri, val in enumerate(reversed(foo)))
]
Result:
[6, 4, 2]
you can use a generator:
li = [1,2,3,4,5,6]
len_li = len(li)
gen = (len_li-1-i for i in range(len_li))
finally:
for i in gen:
print(li[i])
hope this help you.
I’m confused why the obvious choice did not pop up so far:
If reversed()
is not working because you have a generator (as the case with enumerate()
), just use sorted()
:
>>> l = list( 'abcdef' )
>>> sorted( enumerate(l), reverse=True )
[(5, 'f'), (4, 'e'), (3, 'd'), (2, 'c'), (1, 'b'), (0, 'a')]
As a beginner in python, I found this way more easy to understand and reverses a list.
say numlst = [1, 2, 3, 4]
for i in range(len(numlst)-1,-1,-1):
ie., for i in range(3,-1,-1), where 3 is length of list minus 1,
second -1 means list starts from last element and
third -1 signifies it will traverse in reverse order.
print( numlst[ i ] )
o/p = 4, 3, 2, 1
How do I traverse a list in reverse order in Python? So I can start from collection[len(collection)-1]
and end in collection[0]
.
I also want to be able to access the loop index.
Use the built-in reversed()
function:
>>> a = ["foo", "bar", "baz"]
>>> for i in reversed(a):
... print(i)
...
baz
bar
foo
To also access the original index, use enumerate()
on your list before passing it to reversed()
:
>>> for i, e in reversed(list(enumerate(a))):
... print(i, e)
...
2 baz
1 bar
0 foo
Since enumerate()
returns a generator and generators can’t be reversed, you need to convert it to a list
first.
Use list.reverse()
and then iterate as you normally would.
the reverse function comes in handy here:
myArray = [1,2,3,4]
myArray.reverse()
for x in myArray:
print x
You can do:
for item in my_list[::-1]:
print item
(Or whatever you want to do in the for loop.)
The [::-1]
slice reverses the list in the for loop (but won’t actually modify your list “permanently”).
If you need the loop index, and don’t want to traverse the entire list twice, or use extra memory, I’d write a generator.
def reverse_enum(L):
for index in reversed(xrange(len(L))):
yield index, L[index]
L = ['foo', 'bar', 'bas']
for index, item in reverse_enum(L):
print index, item
It can be done like this:
for i in range(len(collection)-1, -1, -1):
print collection[i]
# print(collection[i]) for python 3. +
So your guess was pretty close 🙂 A little awkward but it’s basically saying: start with 1 less than len(collection)
, keep going until you get to just before -1, by steps of -1.
Fyi, the help
function is very useful as it lets you view the docs for something from the Python console, eg:
help(range)
The reversed
builtin function is handy:
for item in reversed(sequence):
The documentation for reversed explains its limitations.
For the cases where I have to walk a sequence in reverse along with the index (e.g. for in-place modifications changing the sequence length), I have this function defined an my codeutil module:
from six.moves import zip as izip, range as xrange
def reversed_enumerate(sequence):
return izip(
reversed(xrange(len(sequence))),
reversed(sequence),
)
This one avoids creating a copy of the sequence. Obviously, the reversed
limitations still apply.
The other answers are good, but if you want to do as
List comprehension style
collection = ['a','b','c']
[item for item in reversed( collection ) ]
How about without recreating a new list, you can do by indexing:
>>> foo = ['1a','2b','3c','4d']
>>> for i in range(len(foo)):
... print foo[-(i+1)]
...
4d
3c
2b
1a
>>>
OR
>>> length = len(foo)
>>> for i in range(length):
... print foo[length-i-1]
...
4d
3c
2b
1a
>>>
def reverse(spam):
k = []
for i in spam:
k.insert(0,i)
return "".join(k)
I like the one-liner generator approach:
((i, sequence[i]) for i in reversed(xrange(len(sequence))))
>>> l = ["a","b","c","d"]
>>> l.reverse()
>>> l
['d', 'c', 'b', 'a']
OR
>>> print l[::-1]
['d', 'c', 'b', 'a']
To use negative indices: start at -1 and step back by -1 at each iteration.
>>> a = ["foo", "bar", "baz"]
>>> for i in range(-1, -1*(len(a)+1), -1):
... print i, a[i]
...
-1 baz
-2 bar
-3 foo
You can also use a while
loop:
i = len(collection)-1
while i>=0:
value = collection[i]
index = i
i-=1
An approach with no imports:
for i in range(1,len(arr)+1):
print(arr[-i])
Time complexity O(n) and space complexity O(1).
An approach that creates a new list in memory, be careful with large lists:
for i in arr[::-1]:
print(i)
Time complexity O(n) and space complexity O(n).
for what ever it’s worth you can do it like this too. very simple.
a = [1, 2, 3, 4, 5, 6, 7]
for x in xrange(len(a)):
x += 1
print a[-x]
You can use a negative index in an ordinary for loop:
>>> collection = ["ham", "spam", "eggs", "baked beans"]
>>> for i in range(1, len(collection) + 1):
... print(collection[-i])
...
baked beans
eggs
spam
ham
To access the index as though you were iterating forward over a reversed copy of the collection, use i - 1
:
>>> for i in range(1, len(collection) + 1):
... print(i-1, collection[-i])
...
0 baked beans
1 eggs
2 spam
3 ham
To access the original, un-reversed index, use len(collection) - i
:
>>> for i in range(1, len(collection) + 1):
... print(len(collection)-i, collection[-i])
...
3 baked beans
2 eggs
1 spam
0 ham
A simple way :
n = int(input())
arr = list(map(int, input().split()))
for i in reversed(range(0, n)):
print("%d %d" %(i, arr[i]))
Also, you could use either “range” or “count” functions.
As follows:
a = ["foo", "bar", "baz"]
for i in range(len(a)-1, -1, -1):
print(i, a[i])
3 baz
2 bar
1 foo
You could also use “count” from itertools as following:
a = ["foo", "bar", "baz"]
from itertools import count, takewhile
def larger_than_0(x):
return x > 0
for x in takewhile(larger_than_0, count(3, -1)):
print(x, a[x-1])
3 baz
2 bar
1 foo
In python 3, list creates a copy, so reversed(list(enumerate(collection))
could be inefficient, generating yet an other list is not optimized away.
If collection is a list for sure, then it may be best to hide the complexity behind an iterator
def reversed_enumerate(collection: list):
for i in range(len(collection)-1, -1, -1):
yield i, collection[i]
so, the cleanest is:
for i, elem in reversed_enumerate(['foo', 'bar', 'baz']):
print(i, elem)
input_list = ['foo','bar','baz']
for i in range(-1,-len(input_list)-1,-1)
print(input_list[i])
i think this one is also simple way to do it… read from end and keep decrementing till the length of list, since we never execute the “end” index hence added -1 also
If you need the index and your list is small, the most readable way is to do reversed(list(enumerate(your_list)))
like the accepted answer says. But this creates a copy of your list, so if your list is taking up a large portion of your memory you’ll have to subtract the index returned by enumerate(reversed())
from len()-1
.
If you just need to do it once:
a = ['b', 'd', 'c', 'a']
for index, value in enumerate(reversed(a)):
index = len(a)-1 - index
do_something(index, value)
or if you need to do this multiple times you should use a generator:
def enumerate_reversed(lyst):
for index, value in enumerate(reversed(lyst)):
index = len(lyst)-1 - index
yield index, value
for index, value in enumerate_reversed(a):
do_something(index, value)
Assuming task is to find last element that satisfies some condition in a list (i.e. first when looking backwards), I’m getting following numbers.
Python 2:
>>> min(timeit.repeat('for i in xrange(len(xs)-1,-1,-1):n if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))
4.6937971115112305
>>> min(timeit.repeat('for i in reversed(xrange(0, len(xs))):n if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))
4.809093952178955
>>> min(timeit.repeat('for i, x in enumerate(reversed(xs), 1):n if 128 == x: break', setup='xs, n = range(256), 0', repeat=8))
4.931743860244751
>>> min(timeit.repeat('for i, x in enumerate(xs[::-1]):n if 128 == x: break', setup='xs, n = range(256), 0', repeat=8))
5.548468112945557
>>> min(timeit.repeat('for i in xrange(len(xs), 0, -1):n if 128 == xs[i - 1]: break', setup='xs, n = range(256), 0', repeat=8))
6.286104917526245
>>> min(timeit.repeat('i = len(xs)nwhile 0 < i:n i -= 1n if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))
8.384078979492188
So, the ugliest option xrange(len(xs)-1,-1,-1)
is the fastest.
Python 3 (different machine):
>>> timeit.timeit('for i in range(len(xs)-1,-1,-1):n if 128 == xs[i]: break', setup='xs, n = range(256), 0', number=400000)
4.48873088900001
>>> timeit.timeit('for i in reversed(range(0, len(xs))):n if 128 == xs[i]: break', setup='xs, n = range(256), 0', number=400000)
4.540959084000008
>>> timeit.timeit('for i, x in enumerate(reversed(xs), 1):n if 128 == x: break', setup='xs, n = range(256), 0', number=400000)
1.9069805409999958
>>> timeit.timeit('for i, x in enumerate(xs[::-1]):n if 128 == x: break', setup='xs, n = range(256), 0', number=400000)
2.960720073999994
>>> timeit.timeit('for i in range(len(xs), 0, -1):n if 128 == xs[i - 1]: break', setup='xs, n = range(256), 0', number=400000)
5.316207007999992
>>> timeit.timeit('i = len(xs)nwhile 0 < i:n i -= 1n if 128 == xs[i]: break', setup='xs, n = range(256), 0', number=400000)
5.802550058999998
Here, enumerate(reversed(xs), 1)
is the fastest.
If you don’t mind the index being negative, you can do:
>>> a = ["foo", "bar", "baz"]
>>> for i in range(len(a)):
... print(~i, a[~i]))
-1 baz
-2 bar
-3 foo
I think the most elegant way is to transform enumerate
and reversed
using the following generator
(-(ri+1), val) for ri, val in enumerate(reversed(foo))
which generates a the reverse of the enumerate
iterator
Example:
foo = [1,2,3]
bar = [3,6,9]
[
bar[i] - val
for i, val in ((-(ri+1), val) for ri, val in enumerate(reversed(foo)))
]
Result:
[6, 4, 2]
you can use a generator:
li = [1,2,3,4,5,6]
len_li = len(li)
gen = (len_li-1-i for i in range(len_li))
finally:
for i in gen:
print(li[i])
hope this help you.
I’m confused why the obvious choice did not pop up so far:
If reversed()
is not working because you have a generator (as the case with enumerate()
), just use sorted()
:
>>> l = list( 'abcdef' )
>>> sorted( enumerate(l), reverse=True )
[(5, 'f'), (4, 'e'), (3, 'd'), (2, 'c'), (1, 'b'), (0, 'a')]
As a beginner in python, I found this way more easy to understand and reverses a list.
say numlst = [1, 2, 3, 4]
for i in range(len(numlst)-1,-1,-1):
ie., for i in range(3,-1,-1), where 3 is length of list minus 1,
second -1 means list starts from last element and
third -1 signifies it will traverse in reverse order.
print( numlst[ i ] )
o/p = 4, 3, 2, 1