Je peux donc commencer len(collection)
et finir collection[0]
.
Je veux également pouvoir accéder à l'index de boucle.
Je peux donc commencer len(collection)
et finir collection[0]
.
Je veux également pouvoir accéder à l'index de boucle.
Réponses:
Utilisez la reversed()
fonction 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, utilisez enumerate()
sur votre liste avant de le transmettre à reversed()
:
>>> for i, e in reversed(list(enumerate(a))):
... print(i, e)
...
2 baz
1 bar
0 foo
Étant donné que les enumerate()
retours d'un générateur et des générateurs ne peuvent pas être inversés, vous devez le convertir en list
premier.
reversed()
ne modifie pas la liste. reversed()
ne fait pas de copie de la liste (sinon il faudrait O (N) de mémoire supplémentaire). Si vous devez modifier la liste, utilisez alist.reverse()
; si vous avez besoin d'une copie de la liste dans l'ordre inverse, utilisez alist[::-1]
.
Tu peux faire:
for item in my_list[::-1]:
print item
(Ou tout ce que vous voulez faire dans la boucle for.)
La [::-1]
tranche inverse la liste dans la boucle for (mais ne modifiera pas réellement votre liste "définitivement").
[::-1]
crée une copie superficielle, donc il ne change pas le tableau ni "de façon permanente" ni "temporaire".
0
, probablement -1
, se termine donc au début ) et étape : -1
(itère en arrière dans la liste, 1
élément à la fois).
reversed()
Si vous avez besoin de l'index de boucle et que vous ne voulez pas parcourir deux fois la liste entière 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
reversed(xrange(len(L)))
produit les mêmes indices que xrange(len(L)-1, -1, -1)
.
for index, item in enumerate(reversed(L)): print len(L)-1-index, item
Cela peut se faire comme ceci:
pour i dans la plage (len (collection) -1, -1, -1): collection d'impression [i] # print (collection [i]) pour python 3. +
Donc, votre supposition était assez proche :) Un peu gênant, mais il dit essentiellement: commencez avec 1 de moins len(collection)
, continuez jusqu'à ce que vous arriviez juste avant -1, par pas de -1.
Pour info, la help
fonction est très utile car elle vous permet de visualiser les documents pour quelque chose à partir de la console Python, par exemple:
help(range)
-1
. Je dirais justereversed(xrange(len(collection)))
La reversed
fonction intégrée est pratique:
for item in reversed(sequence):
La documentation de reverse explique ses limites.
Pour les cas où je dois parcourir une séquence en sens inverse avec l'index (par exemple pour les 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),
)
Celui-ci évite de créer une copie de la séquence. De toute évidence, les reversed
limitations s'appliquent toujours.
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
>>>
OU
>>> length = len(foo)
>>> for i in range(length):
... print foo[length-i-1]
...
4d
3c
2b
1a
>>>
Vous pouvez également utiliser les fonctions "plage" ou "nombre". 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" d'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
3 foo\n2 bar\n1 baz
Utilisez list.reverse()
puis répétez comme vous le feriez normalement.
Une manière 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 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()
Si vous avez besoin de l'index et que votre liste est petite, le moyen le plus lisible est de faire reversed(list(enumerate(your_list)))
comme le dit la réponse acceptée. Mais cela crée une copie de votre liste, donc si votre liste prend une grande partie de votre mémoire , vous devez 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 utile ici:
myArray = [1,2,3,4]
myArray.reverse()
for x in myArray:
print x
Vous pouvez utiliser un indice 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 faisiez une itération 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 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
Je pense que la façon la plus élégante est de transformer enumerate
et d' reversed
utiliser le générateur suivant
(-(ri+1), val) for ri, val in enumerate(reversed(foo))
ce qui génère l'inverse de l' enumerate
itérateur
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]
Les autres réponses sont bonnes, mais si vous voulez faire comme style de compréhension de liste
collection = ['a','b','c']
[item for item in reversed( collection ) ]
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 également un moyen simple de le faire ... lire depuis la fin et continuer à décrémenter jusqu'à la longueur de la liste, car nous n'exécutons jamais l'index "end", donc ajouté -1 également
En supposant que la tâche consiste à trouver le dernier élément qui remplit une condition dans une liste (c'est-à-dire d'abord en regardant en arrière), j'obtiens les 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 xrange(len(xs)-1,-1,-1)
la plus laide est la plus rapide.