在Python中以相反的顺序遍历列表

如何在Python中以相反的顺序遍历列表?所以我可以从collection[len(collection)-1]开始并以collection[0]结束。

我还希望能够访问循环索引。

1138181 次浏览

使用内置的reversed()函数:

>>> a = ["foo", "bar", "baz"]>>> for i in reversed(a):...     print(i)...bazbarfoo

要访问原始索引,请在将列表传递给reversed()之前在列表中使用enumerate()

>>> for i, e in reversed(list(enumerate(a))):...     print(i, e)...2 baz1 bar0 foo

由于enumerate()返回一个生成器并且生成器不能反转,因此您需要先将其转换为list

使用list.reverse(),然后像往常一样迭代。

http://docs.python.org/tutorial/datastructures.html

反向函数在这里派上用场:

myArray = [1,2,3,4]myArray.reverse()for x in myArray:print x

你可以这样做:

for item in my_list[::-1]:print item

(或者你想在for循环中做的任何事情。)

[::-1]切片在for循环中反转列表(但实际上不会“永久”修改您的列表)。

如果你需要循环索引,并且不想遍历整个列表两次,或者使用额外的内存,我会写一个生成器。

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

它可以这样做:

for i in range(len(collection)-1, -1, -1):print collection[i]
# print(collection[i]) for python 3. +

所以你的猜测非常接近:)有点尴尬,但它基本上是说:从小于len(collection)的1开始,继续下去,直到你到达-1之前,通过-1的步骤。

仅供参考,help函数非常有用,因为它可以让您从Python控制台查看某些文档,例如:

help(range)

reversed内置函数很方便:

for item in reversed(sequence):

反转的留档解释了它的局限性。

对于我必须与索引一起反向遍历序列的情况(例如,对于就地修改更改序列长度),我在我的codeutil模块中定义了这个函数:

from six.moves import zip as izip, range as xrange
def reversed_enumerate(sequence):return izip(reversed(xrange(len(sequence))),reversed(sequence),)

这个避免了创建序列的副本。显然,reversed限制仍然适用。

其他答案都很好,但如果你想这样做列表理解样式

collection = ['a','b','c'][item for item in reversed( collection ) ]

在不重新创建新列表的情况下,您可以通过索引来完成:

>>> foo = ['1a','2b','3c','4d']>>> for i in range(len(foo)):...     print foo[-(i+1)]...4d3c2b1a>>>

>>> length = len(foo)>>> for i in range(length):...     print foo[length-i-1]...4d3c2b1a>>>
def reverse(spam):k = []for i in spam:k.insert(0,i)return "".join(k)

我喜欢单线生成器方法:

((i, sequence[i]) for i in reversed(xrange(len(sequence))))
>>> l = ["a","b","c","d"]>>> l.reverse()>>> l['d', 'c', 'b', 'a']

>>> print l[::-1]['d', 'c', 'b', 'a']

要使用负索引:从-1开始,每次迭代后退-1。

>>> a = ["foo", "bar", "baz"]>>> for i in range(-1, -1*(len(a)+1), -1):...     print i, a[i]...-1 baz-2 bar-3 foo

你也可以使用while循环:

i = len(collection)-1while i>=0:value = collection[i]index = ii-=1

没有导入的方法:

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

时间复杂度O(n)和空间复杂度O(1)。

一种在内存中创建新列表的方法,注意大列表:

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

时间复杂度O(n)和空间复杂度O(n)。

不管它值多少钱,你也可以这样做,很简单。

a = [1, 2, 3, 4, 5, 6, 7]for x in xrange(len(a)):x += 1print a[-x]

您可以在普通的for循环中使用负索引:

>>> collection = ["ham", "spam", "eggs", "baked beans"]>>> for i in range(1, len(collection) + 1):...     print(collection[-i])...baked beanseggsspamham

要像在集合的反向副本上向前迭代一样访问索引,请使用i - 1

>>> for i in range(1, len(collection) + 1):...     print(i-1, collection[-i])...0 baked beans1 eggs2 spam3 ham

要访问原始的、未反转的索引,请使用len(collection) - i

>>> for i in range(1, len(collection) + 1):...     print(len(collection)-i, collection[-i])...3 baked beans2 eggs1 spam0 ham

一个简单的方法:

n = int(input())arr = list(map(int, input().split()))
for i in reversed(range(0, n)):print("%d %d" %(i, arr[i]))

此外,您可以使用“范围”或“计数”函数。如下:

a = ["foo", "bar", "baz"]for i in range(len(a)-1, -1, -1):print(i, a[i])
3 baz2 bar1 foo

您还可以使用iterols中的“计数”,如下所示:

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 baz2 bar1 foo

在python 3中,list创建了一个副本,因此reversed(list(enumerate(collection))可能效率低下,生成另一个列表并没有优化。

如果集合确实是一个列表,那么最好隐藏迭代器背后的复杂性

def reversed_enumerate(collection: list):for i in range(len(collection)-1, -1, -1):yield i, collection[i]

最干净的是:

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])

我认为这也是一种简单的方法……从end开始读取并保持递减直到列表的长度,因为我们从不执行“end”索引,因此也添加了-1

如果你需要索引,而你的列表很小,最易读的方法是像接受的答案所说的那样做reversed(list(enumerate(your_list)))。但这会创建一个列表的副本,所以如果你的列表占用了很大一部分内存,你必须从len()-1中减去enumerate(reversed())返回的索引。

如果你只需要做一次:

a = ['b', 'd', 'c', 'a']
for index, value in enumerate(reversed(a)):index = len(a)-1 - index
do_something(index, value)

或者如果你需要多次这样做,你应该使用生成器:

def enumerate_reversed(lyst):for index, value in enumerate(reversed(lyst)):index = len(lyst)-1 - indexyield index, value
for index, value in enumerate_reversed(a):do_something(index, value)

假设任务是找到满足列表中某些条件的最后一个元素(即向后看时首先),我得到以下数字。

python2:

>>> 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 -= 1\n    if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))8.384078979492188

所以,最丑的选项xrange(len(xs)-1,-1,-1)是最快的。

Python 3(不同的机器):

>>> 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 -= 1\n    if 128 == xs[i]: break', setup='xs, n = range(256), 0', number=400000)5.802550058999998

enumerate(reversed(xs), 1)是最快的。

如果你不介意指数为负,你可以这样做:

>>> a = ["foo", "bar", "baz"]>>> for i in range(len(a)):...     print(~i, a[~i]))-1 baz-2 bar-3 foo

我认为最优雅的方法是使用以下生成器转换enumeratereversed

(-(ri+1), val) for ri, val in enumerate(reversed(foo))

它生成enumerate迭代器的反向

示例:

foo = [1,2,3]bar = [3,6,9][bar[i] - valfor i, val in ((-(ri+1), val) for ri, val in enumerate(reversed(foo)))]

结果:

[6, 4, 2]

您可以使用生成器:

li = [1,2,3,4,5,6]len_li = len(li)gen = (len_li-1-i for i in range(len_li))

最后:

for i in gen:print(li[i])

希望这对你有帮助。

我很困惑为什么到目前为止没有出现明显的选择:

如果reversed()不起作用,因为你有一个生成器(如enumerate()的情况),只需使用sorted()

>>> l = list( 'abcdef' )>>> sorted( enumerate(l), reverse=True )[(5, 'f'), (4, 'e'), (3, 'd'), (2, 'c'), (1, 'b'), (0, 'a')]

作为Python的初学者,我发现这种方式更容易理解,并颠倒了列表。

说数字=[1,2,3,4]

对于范围内的i(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 andthird -1 signifies it will traverse in reverse order.

print(numlst[i])第一行

o/p=4,3,2,1