Quindi posso iniziare len(collection)
e finire collection[0]
.
Voglio anche essere in grado di accedere all'indice del ciclo.
Quindi posso iniziare len(collection)
e finire collection[0]
.
Voglio anche essere in grado di accedere all'indice del ciclo.
Risposte:
Utilizzare la reversed()
funzione integrata:
>>> a = ["foo", "bar", "baz"]
>>> for i in reversed(a):
... print(i)
...
baz
bar
foo
Per accedere anche all'indice originale, utilizzare enumerate()
l'elenco prima di passarlo a reversed()
:
>>> for i, e in reversed(list(enumerate(a))):
... print(i, e)
...
2 baz
1 bar
0 foo
Poiché enumerate()
restituisce un generatore e i generatori non possono essere invertiti, è necessario convertirlo in un list
primo.
reversed()
non modifica l'elenco. reversed()
non crea una copia dell'elenco (altrimenti richiederebbe O (N) memoria aggiuntiva). Se è necessario modificare l'elenco utilizzare alist.reverse()
; se è necessaria una copia dell'elenco in ordine inverso, utilizzare alist[::-1]
.
Tu puoi fare:
for item in my_list[::-1]:
print item
(O qualunque cosa tu voglia fare nel ciclo for.)
La [::-1]
sezione inverte l'elenco nel ciclo for (ma in realtà non modificherà l'elenco in modo "permanente").
[::-1]
crea una copia superficiale, quindi non cambia l'array né "permanentemente" né "temporaneo".
0
, probabilmente -1
, quindi termina all'inizio ) e passaggio : -1
(scorre indietro nell'elenco, 1
elemento alla volta).
reversed()
Se hai bisogno dell'indice di loop e non vuoi attraversare l'intero elenco due volte o utilizzare memoria aggiuntiva, scriverei un generatore.
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)))
produce gli stessi indici di xrange(len(L)-1, -1, -1)
.
for index, item in enumerate(reversed(L)): print len(L)-1-index, item
Si può fare così:
per i nell'intervallo (len (raccolta) -1, -1, -1): collezione di stampa [i] # print (collection [i]) per python 3. +
Quindi la tua ipotesi era abbastanza vicina :) Un po 'imbarazzante ma in pratica sta dicendo: inizia con 1 in meno di len(collection)
, continua fino a quando non arrivi a poco prima di -1, con passi di -1.
Cordiali saluti, la help
funzione è molto utile in quanto consente di visualizzare i documenti per qualcosa dalla console di Python, ad esempio:
help(range)
-1
. Vorrei solo direreversed(xrange(len(collection)))
La reversed
funzione integrata è utile:
for item in reversed(sequence):
La documentazione per invertito spiega i suoi limiti.
Per i casi in cui devo percorrere una sequenza al contrario insieme all'indice (ad es. Per modifiche sul posto che cambiano la lunghezza della sequenza), ho questa funzione definita un mio modulo codeutil:
import itertools
def reversed_enumerate(sequence):
return itertools.izip(
reversed(xrange(len(sequence))),
reversed(sequence),
)
Questo evita di creare una copia della sequenza. Ovviamente, le reversed
limitazioni si applicano ancora.
Che ne dite senza ricreare un nuovo elenco, puoi farlo indicizzando:
>>> foo = ['1a','2b','3c','4d']
>>> for i in range(len(foo)):
... print foo[-(i+1)]
...
4d
3c
2b
1a
>>>
O
>>> length = len(foo)
>>> for i in range(length):
... print foo[length-i-1]
...
4d
3c
2b
1a
>>>
Inoltre, è possibile utilizzare le funzioni "intervallo" o "conteggio". Come segue:
a = ["foo", "bar", "baz"]
for i in range(len(a)-1, -1, -1):
print(i, a[i])
3 baz
2 bar
1 foo
Puoi anche usare "count" da itertools come segue:
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
Utilizzare list.reverse()
e quindi iterare normalmente.
Un modo espressivo per ottenere reverse(enumerate(collection))
in Python 3:
zip(reversed(range(len(collection))), reversed(collection))
in Python 2:
izip(reversed(xrange(len(collection))), reversed(collection))
Non sono sicuro del motivo per cui non abbiamo una scorciatoia per questo, ad es .:
def reversed_enumerate(collection):
return zip(reversed(range(len(collection))), reversed(collection))
o perché non abbiamo reversed_range()
Se hai bisogno dell'indice e la tua lista è piccola, il modo più leggibile è fare reversed(list(enumerate(your_list)))
come dice la risposta accettata. Ma questo crea una copia della vostra lista, quindi se la vostra lista sta prendendo una grande parte della memoria si dovrà sottrarre l'indice restituito da enumerate(reversed())
dalen()-1
.
Se hai solo bisogno di farlo una volta:
a = ['b', 'd', 'c', 'a']
for index, value in enumerate(reversed(a)):
index = len(a)-1 - index
do_something(index, value)
o se devi farlo più volte dovresti usare un generatore:
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 funzione inversa è utile qui:
myArray = [1,2,3,4]
myArray.reverse()
for x in myArray:
print x
Puoi usare un indice negativo in un normale ciclo per:
>>> collection = ["ham", "spam", "eggs", "baked beans"]
>>> for i in range(1, len(collection) + 1):
... print(collection[-i])
...
baked beans
eggs
spam
ham
Per accedere all'indice come se stessi ripetendo una copia invertita della raccolta, usa i - 1
:
>>> for i in range(1, len(collection) + 1):
... print(i-1, collection[-i])
...
0 baked beans
1 eggs
2 spam
3 ham
Per accedere all'indice originale non invertito, utilizzare 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
Penso che il modo più elegante sia quello di trasformare enumerate
e reversed
utilizzare il seguente generatore
(-(ri+1), val) for ri, val in enumerate(reversed(foo))
che genera un contrario enumerate
dell'iteratore
Esempio:
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)))
]
Risultato:
[6, 4, 2]
Le altre risposte sono buone, ma se vuoi fare come stile di comprensione dell'elenco
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])
penso che questo sia anche un modo semplice per farlo ... leggi da fine e continua a diminuire fino alla lunghezza della lista, dal momento che non eseguiamo mai l'indice "end" quindi aggiunto -1 anche
Supponendo che il compito sia trovare l'ultimo elemento che soddisfi alcune condizioni in un elenco (ovvero prima guardando indietro), sto ottenendo i seguenti numeri:
>>> 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
Quindi, l'opzione più brutta xrange(len(xs)-1,-1,-1)
è la più veloce.