Parcourir une liste dans L'ordre inverse en Python
donc je peux commencer par len(collection)
et finir par collection[0]
.
EDIT: Désolé, j'ai oublié de mentionner que je veux aussi être en mesure d'accéder à l'indice de boucle.
24 réponses
utiliser la reversed()
fonction intégrée:
>>> a = ["foo", "bar", "baz"]
>>> for i in reversed(a):
... print i
...
baz
bar
foo
pour accéder aussi à l'index original:
>>> for i, e in reversed(list(enumerate(a))):
... print i, e
...
2 baz
1 bar
0 foo
Vous pouvez le faire:
for item in my_list[::-1]:
print item
(Ou ce que vous voulez faire dans la boucle for.)
la tranche [::-1]
inverse la liste dans la boucle for (mais ne modifiera pas réellement votre liste "de façon permanente").
si vous avez besoin de l'index de boucle, et que vous ne voulez pas parcourir la liste entière deux fois, ou 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
Il peut être fait comme ceci:
for i in range(len(collection)-1, -1, -1): print collection[i] # print(collection[i]) for python 3. +
donc votre supposition était assez proche :) un peu maladroit mais il est fondamentalement dire: commencer par 1 de moins que len(collection)
, continuez jusqu'à ce que vous arrivez à juste avant -1, par étapes de -1.
pour Info, la fonction help
est très utile car elle vous permet de voir les docs pour quelque chose depuis la console Python, par exemple:
help(range)
la fonction reversed
est pratique:
for item in reversed(sequence):
la documentation pour inversé explique ses limites.
pour les cas où je dois parcourir une séquence en marche arrière avec l'index (par exemple pour des modifications sur place modifiant la longueur de la séquence), j'ai cette fonction définie un module my codeutil:
import itertools
def reversed_enumerate(sequence):
return itertools.izip(
reversed(xrange(len(sequence))),
reversed(sequence),
)
Cela évite de créer une copie de la séquence. De toute évidence, les restrictions reversed
s'appliquent toujours.
>>> l = ["a","b","c","d"]
>>> l.reverse()
>>> l
['d', 'c', 'b', 'a']
ou
>>> print l[::-1]
['d', 'c', 'b', 'a']
Que diriez-vous de 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
>>>
ou
>>> length = len(foo)
>>> for i in range(length):
... print foo[length-i-1]
...
4d
3c
2b
1a
>>>
j'aime les one-liner générateur approche:
((i, sequence[i]) for i in reversed(xrange(len(sequence))))
utilisez list.reverse()
puis itérez comme vous le feriez normalement.
def reverse(spam):
k = []
for i in spam:
k.insert(0,i)
return "".join(k)
autres réponses sont bonnes, mais si vous voulez faire comme List understanding style
collection = ['a','b','c']
[item for item in reversed( collection ) ]
utiliser la fonction intégrée reversed()
pour l'objet de séquence, cette méthode a l'effet de toutes les séquences
vous pouvez également utiliser une while
boucle:
i = len(collection)-1
while i>=0:
value = collection[i]
index = i
i-=1
une approche facile est:
for i in range(1,len(arr)+1):
print(arr[-i])
pour ce que ça vaut, tu peux le faire comme ça aussi. très simple.
a = [1, 2, 3, 4, 5, 6, 7]
for x in xrange(len(a)):
x += 1
print a[-x]
vous pouvez utiliser un indice négatif dans une boucle 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 itériez vers l'avant sur 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 original 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
la fonction inverse est utile ici:
myArray = [1,2,3,4]
myArray.reverse()
for x in myArray:
print x
pour utiliser des indices négatifs: démarrer à -1 et reculer 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
Une manière simple :
n = int(input())
arr = list(map(int, input().split()))
for i in reversed(range(0, n)):
print("%d %d" %(i, arr[i]))
une façon expressive de réaliser 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 suis pas sûr pourquoi nous n'avons pas un 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()
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 une façon simple de le faire... lire à partir de fin et continuer à décrémenter jusqu'à la longueur de la liste, puisque nous n'exécutons jamais l'index "fin" donc ajouté -1 aussi
si vous avez besoin de l'indice, la façon la plus simple est de soustraire l'indice retourné par enumerate(reversed())
de len()-1
. enumerate()
ne prend pas un argument step
.
si vous devez faire cela plusieurs fois, vous devriez 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 qu'une fois:
for index, value in enumerate(reversed(a)):
index = len(a)-1 - index
do_something(index, value)
en supposant que la tâche est de trouver le dernier élément qui satisfait à une condition dans une liste (i.e. premier en regardant en arrière), je reçois les nombres suivants:
>>> 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 moche xrange(len(xs)-1,-1,-1)
est la plus rapide.
vous pouvez également utiliser les fonctions" range "ou" count". Comme suit:
a = ["foo", "bar", "baz"]
for i in range(len(a), 0, -1):
print(i, a[i-1])
3 baz
2 bar
1 foo
vous pouvez également utiliser "count" des 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