Więc mogę zacząć od len(collection)
i zakończyć collection[0]
.
Chcę także mieć dostęp do indeksu pętli.
Więc mogę zacząć od len(collection)
i zakończyć collection[0]
.
Chcę także mieć dostęp do indeksu pętli.
Odpowiedzi:
Użyj wbudowanej reversed()
funkcji:
>>> a = ["foo", "bar", "baz"]
>>> for i in reversed(a):
... print(i)
...
baz
bar
foo
Aby uzyskać dostęp do oryginalnego indeksu, użyj go enumerate()
na liście przed przekazaniem go do reversed()
:
>>> for i, e in reversed(list(enumerate(a))):
... print(i, e)
...
2 baz
1 bar
0 foo
Ponieważ enumerate()
zwraca generator i generatory nie mogą być odwrócone, musisz przekonwertować go na list
pierwszy.
reversed()
nie modyfikuje listy. reversed()
nie tworzy kopii listy (w przeciwnym razie wymagałoby dodatkowej pamięci O (N)). Jeśli chcesz zmodyfikować listę, użyj alist.reverse()
; jeśli potrzebujesz kopii listy w odwrotnej kolejności użyj alist[::-1]
.
Możesz to zrobić:
for item in my_list[::-1]:
print item
(Lub cokolwiek chcesz zrobić w pętli for.)
[::-1]
Plaster odwraca listy w pętli for (ale nie będzie faktycznie zmodyfikować swoją listę „stałe”).
[::-1]
tworzy płytką kopię, dlatego nie zmienia tablicy ani „na stałe”, ani „tymczasowo”.
0
, prawdopodobnie -1
, więc kończy się na początku ) i krok : -1
(iteruje wstecz przez listę, 1
element na raz).
reversed()
Jeśli potrzebujesz indeksu pętli i nie chcesz dwukrotnie przeglądać całej listy lub użyć dodatkowej pamięci, napisałbym generator.
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)))
produkuje takie same wskaźniki jak xrange(len(L)-1, -1, -1)
.
for index, item in enumerate(reversed(L)): print len(L)-1-index, item
Można to zrobić w następujący sposób:
dla i w zakresie (len (kolekcja) -1, -1, -1): drukuj kolekcję [i] # print (kolekcja [i]) dla Pythona 3. +
Więc twoje przypuszczenie było dość bliskie :) Trochę niezręczne, ale w gruncie rzeczy mówi: zacznij od 1 mniej niż len(collection)
, idź dalej, aż dojdziesz do tuż przed -1, krokami co -1.
Fyi, help
funkcja jest bardzo przydatna, ponieważ pozwala przeglądać dokumenty dotyczące czegoś z konsoli Python, np .:
help(range)
-1
. Chciałbym tylko powiedziećreversed(xrange(len(collection)))
reversed
Funkcja wbudowana jest pod ręką:
for item in reversed(sequence):
Dokumentacja dla odwróconych wyjaśnia swoje ograniczenia.
W przypadkach, w których muszę przejść sekwencję w odwrotnej kolejności wraz z indeksem (np. W przypadku modyfikacji w miejscu zmieniających długość sekwencji), mam tę funkcję, która zdefiniowała mój moduł codeutil:
import itertools
def reversed_enumerate(sequence):
return itertools.izip(
reversed(xrange(len(sequence))),
reversed(sequence),
)
Ten unika tworzenia kopii sekwencji. Oczywiście reversed
ograniczenia nadal obowiązują.
A co powiesz na to, bez ponownego tworzenia nowej listy, możesz to zrobić, indeksując:
>>> foo = ['1a','2b','3c','4d']
>>> for i in range(len(foo)):
... print foo[-(i+1)]
...
4d
3c
2b
1a
>>>
LUB
>>> length = len(foo)
>>> for i in range(length):
... print foo[length-i-1]
...
4d
3c
2b
1a
>>>
Możesz także użyć funkcji „zakres” lub „liczenie”. Następująco:
a = ["foo", "bar", "baz"]
for i in range(len(a)-1, -1, -1):
print(i, a[i])
3 baz
2 bar
1 foo
Możesz również użyć „count” z itertools w następujący sposób:
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
Użyj, list.reverse()
a następnie iteruj tak jak zwykle.
Ekspresyjny sposób na osiągnięcie reverse(enumerate(collection))
w Pythonie 3:
zip(reversed(range(len(collection))), reversed(collection))
w python 2:
izip(reversed(xrange(len(collection))), reversed(collection))
Nie jestem pewien, dlaczego nie mamy na to skrótu, np .:
def reversed_enumerate(collection):
return zip(reversed(range(len(collection))), reversed(collection))
lub dlaczego nie mamy reversed_range()
Jeśli potrzebujesz indeksu, a lista jest niewielka, najbardziej czytelnym sposobem jest zrobienie reversed(list(enumerate(your_list)))
tego, co mówi zaakceptowana odpowiedź. Ale ta tworzy kopię listy, więc jeśli lista jest podejmowanie dużą część swojej pamięci musisz odjąć wskaźnik zwracany przez enumerate(reversed())
z len()-1
.
Jeśli musisz to zrobić tylko raz:
a = ['b', 'd', 'c', 'a']
for index, value in enumerate(reversed(a)):
index = len(a)-1 - index
do_something(index, value)
lub jeśli musisz to zrobić wiele razy, powinieneś użyć generatora:
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)
przydatna jest tu funkcja odwrotna:
myArray = [1,2,3,4]
myArray.reverse()
for x in myArray:
print x
Możesz użyć indeksu ujemnego w zwykłej pętli for:
>>> collection = ["ham", "spam", "eggs", "baked beans"]
>>> for i in range(1, len(collection) + 1):
... print(collection[-i])
...
baked beans
eggs
spam
ham
Aby uzyskać dostęp do indeksu, tak jakbyś wykonywał iterację do przodu w odwróconej kopii kolekcji, użyj i - 1
:
>>> for i in range(1, len(collection) + 1):
... print(i-1, collection[-i])
...
0 baked beans
1 eggs
2 spam
3 ham
Aby uzyskać dostęp do oryginalnego, nieodwróconego indeksu, użyj 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
Myślę, że najbardziej eleganckim sposobem jest transformacja enumerate
i reversed
użycie następującego generatora
(-(ri+1), val) for ri, val in enumerate(reversed(foo))
który generuje odwrotność enumerate
iteratora
Przykład:
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)))
]
Wynik:
[6, 4, 2]
Inne odpowiedzi są dobre, ale jeśli chcesz zrobić to w stylu listy
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])
myślę, że ten jest również prostym sposobem na zrobienie tego ... czytaj od końca i zmniejszaj do końca listy, ponieważ nigdy nie wykonujemy indeksu „end”, dlatego dodaliśmy -1
Zakładając, że zadaniem jest znalezienie ostatniego elementu, który spełnia jakiś warunek na liście (tj. Pierwszy, gdy patrzę wstecz), otrzymuję następujące liczby:
>>> 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
Zatem najbrzydsza opcja xrange(len(xs)-1,-1,-1)
jest najszybsza.