web-dev-qa-db-fra.com

Parcourir une liste en ordre inverse en Python

Je peux donc commencer à partir de len(collection) et terminer par collection[0].

EDIT: Désolé, j'ai oublié de mentionner que je veux aussi pouvoir accéder à l'index de la boucle.

553
Joan Venge

Utilisez la fonction reversed() intégrée:

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

Pour accéder également à l'index d'origine:

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

Tu peux faire:

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

(Ou tout ce que vous voulez faire dans la boucle.)

La tranche [::-1] inverse la liste dans la boucle for (mais ne modifiera pas votre liste "de manière permanente").

137
mipadi

Si vous avez besoin de l'index de la boucle et que vous ne voulez pas parcourir la liste entière deux fois, ni utiliser de la mémoire supplémentaire, j'écrirais un générateur. 

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
63
Triptych

Cela peut être fait comme ça:

pour i dans la plage (len (collection) -1, -1, -1): 
 print collection [i] 
 
 # print (collection [i]) pour python 3. + 
 

Donc, votre proposition était assez proche :) Un peu gênant, mais il dit en gros: commencez avec 1 moins que len(collection), continuez jusqu'à ce que vous arriviez juste avant -1, par pas de -1.

Fyi, la fonction help est très utile car elle vous permet d’afficher la documentation de quelque chose à partir de la console Python, par exemple:

help(range)

54
Alan Rowarth

La fonction intégrée reversed est pratique:

for item in reversed(sequence):

La documentation for reverse explique ses limites.

Dans les cas où je dois parcourir une séquence en sens inverse avec l'index (par exemple, pour des modifications sur place modifiant la longueur de la séquence), cette fonction est définie dans un module mon code

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

Celui-ci évite de créer une copie de la séquence. De toute évidence, les limitations reversed s'appliquent toujours.

20
tzot
>>> l = ["a","b","c","d"]
>>> l.reverse()
>>> l
['d', 'c', 'b', 'a']

OR

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

J'aime l'approche génératrice à une ligne:

((i, sequence[i]) for i in reversed(xrange(len(sequence))))
5
lkraider

Que diriez-vous sans recréer une nouvelle liste, vous pouvez le faire en indexant:

>>> 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
>>>
5
James Sapam

Utilisez list.reverse() et effectuez une nouvelle itération comme vous le feriez normalement.

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

3
Bill Konrad
def reverse(spam):
    k = []
    for i in spam:
        k.insert(0,i)
    return "".join(k)
2
Jase

Vous pouvez également utiliser les fonctions "plage" ou "compte". Comme suit:

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

3 baz
2 bar
1 foo

Vous pouvez également utiliser "count" dans itertools comme suit:

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
2
disooqi

pour ce que ça vaut jamais, tu peux le faire aussi. très simple.

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

Une approche simple consiste à:

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

Les autres réponses sont bonnes, mais si vous voulez faire comme Liste style de compréhension

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

Un moyen expressif d’atteindre reverse(enumerate(collection)) en python 3:

Zip(reversed(range(len(collection))), reversed(collection))

en python 2:

izip(reversed(xrange(len(collection))), reversed(collection))

Je ne sais pas pourquoi nous n'avons pas de raccourci pour cela, par exemple:

def reversed_enumerate(collection):
    return Zip(reversed(range(len(collection))), reversed(collection))

ou pourquoi nous n'avons pas reversed_range()

1
Barnabas Szabolcs

Vous pouvez utiliser un index négatif dans une boucle for ordinaire:

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

Pour accéder à l'index comme si vous parcouriez une copie inversée de la collection, utilisez i - 1:

>>> for i in range(1, len(collection) + 1):
...     print(i-1, collection[-i])
... 
0 baked beans
1 eggs
2 spam
3 ham

Pour accéder à l'index d'origine non inversé, utilisez 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
1
Malcolm

Vous pouvez également utiliser une boucle while:

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

utilise la fonction intégrée reversed() pour l'objet séquence, cette méthode a pour effet de toutes les séquences

lien de référence plus détaillé

1
lazybios
a = ["foo", "bar", "baz"]
print a[::~0]

une autre façon de résoudre ce problème, ce code est exécuté décrémenté pour la boucle

1
paras chauhan

la fonction inverse est pratique ici:

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

Si vous avez besoin de l'index, le moyen le plus simple consiste à soustraire l'index renvoyé par enumerate(reversed()) à len()-1. enumerate() ne prend pas un argument step

Si vous devez le faire plusieurs fois, vous devez utiliser un générateur:

a = ['b', 'd', 'c', 'a']

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)

ou si vous avez juste besoin de le faire une fois:

for index, value in enumerate(reversed(a)):
    index = len(a)-1 - index

    do_something(index, value)
0
Boris

En supposant que la tâche consiste à trouver le dernier élément satisfaisant une condition de la liste (c’est-à-dire d’abord en regardant en arrière), les numéros suivants me sont attribués:

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

Donc, l'option la plus laide xrange(len(xs)-1,-1,-1) est la plus rapide.

0
wonder.mice

Pour utiliser les indices négatifs: commencez à -1 et reculez de -1 à chaque itération.

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

je pense que celui-ci est aussi un moyen simple de le faire ... lisez-le de la fin et continuez à décrémenter jusqu'à la longueur de la liste, car nous n'exécutons jamais l'index "fin" donc ajouté -1 également

0
Varun Maurya

Je pense que la manière la plus élégante est de transformer enumerate et reversed en utilisant le générateur suivant

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

ce qui génère l'inverse de l'itérateur enumerate

Exemple:

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

Résultat:

[6, 4, 2]
0
CervEd

Un moyen simple: 

n = int(input())
arr = list(map(int, input().split()))

for i in reversed(range(0, n)):
    print("%d %d" %(i, arr[i]))
0
rashedcs

Si l'index n'est pas négatif, vous pouvez faire:

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