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:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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.
Method 2
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”).
Method 3
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)
Method 4
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
Method 5
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.
Method 6
An approach with no imports:
for i in range(1,len(arr)+1):
print(arr[-i])
or, this approach will create a new list in memory so be careful with large lists
for i in arr[::-1]:
print(i)
Method 7
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
Method 8
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 >>>
Method 9
>>> l = ["a","b","c","d"] >>> l.reverse() >>> l ['d', 'c', 'b', 'a']
OR
>>> print l[::-1] ['d', 'c', 'b', 'a']
Method 10
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)
Method 11
I like the one-liner generator approach:
((i, sequence[i]) for i in reversed(xrange(len(sequence))))
Method 12
Use list.reverse() and then iterate as you normally would.
http://docs.python.org/tutorial/datastructures.html
Method 13
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]
Method 14
def reverse(spam):
k = []
for i in spam:
k.insert(0,i)
return "".join(k)
Method 15
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)
Method 16
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]
Method 17
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.
Method 18
the reverse function comes in handy here:
myArray = [1,2,3,4]
myArray.reverse()
for x in myArray:
print x
Method 19
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 ) ]
Method 20
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
Method 21
You can also use a while loop:
i = len(collection)-1
while i>=0:
value = collection[i]
index = i
i-=1
Method 22
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
Method 23
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
Method 24
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')]
Method 25
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]))
Method 26
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
Method 27
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.
Method 28
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):
print( numlst[ i ] )
o/p = 4, 3, 2, 1
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0