Обход списка в обратном порядке в Python - PullRequest
593 голосов
/ 09 февраля 2009

Так что я могу начать с len(collection) и оканчиваться на collection[0].

РЕДАКТИРОВАТЬ: Извините, я забыл упомянуть, я также хочу иметь возможность доступа к индексу цикла.

Ответы [ 27 ]

987 голосов
/ 09 февраля 2009

Используйте встроенную функцию reversed():

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

Чтобы также получить доступ к исходному индексу, используйте enumerate() в своем списке перед передачей его reversed():

>>> for i, e in reversed(list(enumerate(a))):
...     print(i, e)
... 
2 baz
1 bar
0 foo

Так как enumerate() возвращает генератор, и генераторы не могут быть обращены, вам нужно сначала преобразовать его в list.

145 голосов
/ 09 февраля 2009

Вы можете сделать:

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

(или все, что вы хотите сделать в цикле for.)

Срез [::-1] переворачивает список в цикле for (но фактически не изменяет ваш список «навсегда»).

63 голосов
/ 09 февраля 2009

Если вам нужен индекс цикла и вы не хотите дважды просматривать весь список или использовать дополнительную память, я бы написал генератор.

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
53 голосов
/ 10 февраля 2009

Это можно сделать так:

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

    # print(collection[i]) for python 3. +

Итак, ваше предположение было довольно близко :) Немного неловко, но в основном говорится: начните с 1, меньшего len(collection), продолжайте, пока не доберетесь до -1, с шагом -1.

Кстати, функция help очень полезна, так как позволяет просматривать документы для чего-либо из консоли Python, например:

help(range)

20 голосов
/ 11 октября 2011

Удобная встроенная функция reversed:

for item in reversed(sequence):

Документация для перевернутого объясняет его ограничения.

Для случаев, когда мне нужно пройти последовательность в обратном порядке вместе с индексом (например, для модификаций на месте, изменяющих длину последовательности), я определил эту функцию для моего модуля codeutil:

import itertools
def reversed_enumerate(sequence):
    return itertools.izip(
        reversed(xrange(len(sequence))),
        reversed(sequence),
    )

Этот позволяет избежать создания копии последовательности. Очевидно, что ограничения reversed остаются в силе.

7 голосов
/ 11 сентября 2015
>>> l = ["a","b","c","d"]
>>> l.reverse()
>>> l
['d', 'c', 'b', 'a']

OR

>>> print l[::-1]
['d', 'c', 'b', 'a']
5 голосов
/ 17 августа 2014

Мне нравится однострочный генератор:

((i, sequence[i]) for i in reversed(xrange(len(sequence))))
5 голосов
/ 06 апреля 2018

Кроме того, вы можете использовать функции «range» или «count». Следующим образом:

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

3 baz
2 bar
1 foo

Вы также можете использовать «count» из itertools следующим образом:

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
5 голосов
/ 15 февраля 2014

Как насчет без воссоздания нового списка, вы можете сделать это путем индексации:

>>> 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
>>>
4 голосов
/ 09 февраля 2009

Используйте list.reverse(), а затем выполняйте итерацию, как обычно.

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

...