Traverse une liste dans l'ordre inverse en Python
Question
Je peux donc commencer à partir len(collection)
et fin en collection[0]
.
EDIT: Désolé, j'ai oublié de mentionner que je veux aussi être en mesure d'accéder à l'index de la boucle
.La solution
Utilisez la fonction intégrée reversed()
:
>>> a = ["foo", "bar", "baz"]
>>> for i in reversed(a):
... print(i)
...
baz
bar
foo
Pour accéder à l'index également d'origine, utilisez enumerate()
sur votre liste avant de passer à reversed()
:
>>> for i, e in reversed(list(enumerate(a))):
... print(i, e)
...
2 baz
1 bar
0 foo
Depuis enumerate()
retourne un générateur et des générateurs ne peut pas être inversée, vous devez le convertir en un premier list
.
Autres conseils
Vous pouvez faire:
for item in my_list[::-1]:
print item
(Ou tout ce que vous voulez faire dans la boucle.)
La tranche de [::-1]
inverse la liste dans la boucle (mais ne modifiera pas réellement votre liste « en permanence »).
Si vous avez besoin de l'indice de la boucle, et ne veulent pas traverser toute la liste deux fois, ou utiliser la mémoire supplémentaire, j'écrirait 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 essentiellement dire: commencer avec moins de 1 len(collection)
, continuez jusqu'à ce que vous obtenez juste avant -1, par étapes de -1.
Fyi, la fonction est help
très utile car il vous permet d'afficher les documents pour quelque chose de la console Python, par exemple:
help(range)
La reversed
fonction est pratique builtin:
for item in reversed(sequence):
La documentation inversée explique ses limites.
Pour les cas où je dois marcher une séquence dans le sens inverse le long de l'indice (par exemple pour en place modifications changeant la longueur de la séquence), I ont cette fonction définie par un module de ma codeutil:
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 de reversed
appliquent encore.
>>> l = ["a","b","c","d"]
>>> l.reverse()
>>> l
['d', 'c', 'b', 'a']
ou
>>> print l[::-1]
['d', 'c', 'b', 'a']
Que diriez-vous sans recréer une nouvelle liste, vous pouvez le faire par l'indexation:
>>> 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 l'approche du générateur en une ligne:
((i, sequence[i]) for i in reversed(xrange(len(sequence))))
En outre, vous pouvez utiliser soit « plage » ou « fonctions de comptage ». 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 de itertools "count" 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
Utilisez list.reverse()
et itérer puis comme vous le feriez normalement.
def reverse(spam):
k = []
for i in spam:
k.insert(0,i)
return "".join(k)
pour ce que jamais il vaut la peine, vous pouvez 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]
Si vous avez besoin de l'index et votre liste est faible, la manière la plus lisible est de faire reversed(list(enumerate(your_list)))
comme la réponse acceptée dit. Mais cela crée une copie de votre liste, donc si votre liste prend une grande partie de votre mémoire, vous devrez soustraire l'indice retourné par enumerate(reversed())
de len()-1
.
Si vous avez juste besoin de le faire une fois:
a = ['b', 'd', 'c', 'a']
for index, value in enumerate(reversed(a)):
index = len(a)-1 - index
do_something(index, value)
ou si vous devez le faire plusieurs fois, vous devez utiliser un générateur:
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)
la fonction inverse est très pratique ici:
myArray = [1,2,3,4]
myArray.reverse()
for x in myArray:
print x
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 ) ]
utiliser la fonction reversed()
intégré pour objet de séquence, ce procédé a pour effet de toutes les séquences
Vous pouvez également utiliser une boucle de while
:
i = len(collection)-1
while i>=0:
value = collection[i]
index = i
i-=1
Vous pouvez utiliser un indice négatif dans une boucle ordinaire pour:
>>> 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érez reportables 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 non inversé, original, 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
Une manière expressive pour 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 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()
Une approche sans les importations:
for i in range(1,len(arr)+1):
print(arr[-i])
ou
for i in arr[::-1]:
print(i)
Pour utiliser les indices négatifs. Commencer à -1 et reculez par -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 façon simple:
n = int(input())
arr = list(map(int, input().split()))
for i in reversed(range(0, n)):
print("%d %d" %(i, arr[i]))
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 moyen simple de le faire ... lire la fin et garder décrémentation jusqu'à ce que la longueur de la liste, puisque nous n'exécutons donc l'indice ajouté -1 « end » aussi
En supposant que la tâche est de trouver le dernier élément qui satisfait une condition dans une liste (à savoir d'abord quand on regarde en arrière), je reçois des numéros 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
Ainsi, l'option la plus laide xrange(len(xs)-1,-1,-1)
est le plus rapide.
Si cela ne vous dérange pas l'index étant 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
Je pense que la façon 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))
qui génère un inverse de l'itérateur de 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]