Jadi saya bisa mulai len(collection)
dan mengakhiri collection[0]
.
Saya juga ingin dapat mengakses indeks loop.
Jadi saya bisa mulai len(collection)
dan mengakhiri collection[0]
.
Saya juga ingin dapat mengakses indeks loop.
Jawaban:
Gunakan reversed()
fungsi bawaan:
>>> a = ["foo", "bar", "baz"]
>>> for i in reversed(a):
... print(i)
...
baz
bar
foo
Untuk juga mengakses indeks asli, gunakan enumerate()
pada daftar Anda sebelum meneruskannya ke reversed()
:
>>> for i, e in reversed(list(enumerate(a))):
... print(i, e)
...
2 baz
1 bar
0 foo
Karena enumerate()
mengembalikan generator dan generator tidak dapat dibatalkan, Anda perlu mengubahnya menjadi yang list
pertama.
reversed()
jangan modifikasi daftar. reversed()
tidak membuat salinan dari daftar (jika tidak maka akan membutuhkan memori tambahan O (N)). Jika Anda perlu mengubah penggunaan daftar alist.reverse()
; jika Anda memerlukan salinan daftar dalam penggunaan terbalik urutan alist[::-1]
.
Anda dapat melakukan:
for item in my_list[::-1]:
print item
(Atau apa pun yang ingin Anda lakukan dalam for loop.)
The [::-1]
slice membalikkan daftar di untuk loop (tetapi tidak akan benar-benar mengubah daftar Anda "permanen").
[::-1]
membuat salinan yang dangkal, oleh karena itu array tidak mengubah "permanen" atau "sementara".
0
, mungkin -1
, jadi berakhir di awal ) dan langkah : -1
(beralih mundur melalui daftar, 1
item sekaligus).
reversed()
Jika Anda memerlukan indeks loop, dan tidak ingin melintasi seluruh daftar dua kali, atau menggunakan memori tambahan, saya akan menulis 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)))
menghasilkan indeks yang sama dengan xrange(len(L)-1, -1, -1)
.
for index, item in enumerate(reversed(L)): print len(L)-1-index, item
Itu bisa dilakukan seperti ini:
untuk saya dalam kisaran (len (koleksi) -1, -1, -1): koleksi cetak [i] # print (koleksi [i]) untuk python 3. +
Jadi tebakan Anda cukup dekat :) Sedikit canggung tetapi pada dasarnya mengatakan: mulai dengan 1 kurang dari len(collection)
, teruskan sampai Anda tiba tepat sebelum -1, dengan langkah-langkah -1.
Fyi, help
fungsi ini sangat berguna karena memungkinkan Anda melihat dokumen untuk sesuatu dari konsol Python, misalnya:
help(range)
-1
. Saya hanya akan mengatakanreversed(xrange(len(collection)))
Fungsi reversed
bawaan berguna:
for item in reversed(sequence):
The dokumentasi untuk terbalik menjelaskan keterbatasan.
Untuk kasus-kasus di mana saya harus menjalankan urutan secara terbalik bersama dengan indeks (misalnya untuk modifikasi di tempat mengubah panjang urutan), saya memiliki fungsi ini mendefinisikan modul codeutil saya:
import itertools
def reversed_enumerate(sequence):
return itertools.izip(
reversed(xrange(len(sequence))),
reversed(sequence),
)
Yang ini menghindari membuat salinan urutan. Jelas, reversed
batasannya masih berlaku.
Bagaimana tanpa membuat ulang daftar baru, Anda dapat melakukannya dengan mengindeks:
>>> foo = ['1a','2b','3c','4d']
>>> for i in range(len(foo)):
... print foo[-(i+1)]
...
4d
3c
2b
1a
>>>
ATAU
>>> length = len(foo)
>>> for i in range(length):
... print foo[length-i-1]
...
4d
3c
2b
1a
>>>
Anda juga dapat menggunakan fungsi "rentang" atau "menghitung". Sebagai berikut:
a = ["foo", "bar", "baz"]
for i in range(len(a)-1, -1, -1):
print(i, a[i])
3 baz
2 bar
1 foo
Anda juga dapat menggunakan "count" dari itertools sebagai berikut:
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
Gunakan list.reverse()
dan kemudian beralih seperti biasa.
Cara ekspresif untuk mencapai reverse(enumerate(collection))
dalam python 3:
zip(reversed(range(len(collection))), reversed(collection))
dalam python 2:
izip(reversed(xrange(len(collection))), reversed(collection))
Saya tidak yakin mengapa kami tidak memiliki tulisan cepat untuk ini, misalnya:
def reversed_enumerate(collection):
return zip(reversed(range(len(collection))), reversed(collection))
atau mengapa kita tidak punya reversed_range()
Jika Anda memerlukan indeks dan daftar Anda kecil, cara yang paling mudah dibaca adalah dengan melakukan reversed(list(enumerate(your_list)))
seperti kata jawaban yang diterima. Tetapi ini membuat salinan daftar Anda, jadi jika daftar Anda mengambil sebagian besar memori Anda, Anda harus mengurangi indeks yang dikembalikan oleh enumerate(reversed())
dari len()-1
.
Jika Anda hanya perlu melakukannya sekali:
a = ['b', 'd', 'c', 'a']
for index, value in enumerate(reversed(a)):
index = len(a)-1 - index
do_something(index, value)
atau jika Anda perlu melakukan ini beberapa kali, Anda harus menggunakan generator:
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)
fungsi sebaliknya sangat berguna di sini:
myArray = [1,2,3,4]
myArray.reverse()
for x in myArray:
print x
Anda dapat menggunakan indeks negatif dalam loop biasa:
>>> collection = ["ham", "spam", "eggs", "baked beans"]
>>> for i in range(1, len(collection) + 1):
... print(collection[-i])
...
baked beans
eggs
spam
ham
Untuk mengakses indeks seolah-olah Anda beralih ke depan atas salinan koleksi yang terbalik, gunakan i - 1
:
>>> for i in range(1, len(collection) + 1):
... print(i-1, collection[-i])
...
0 baked beans
1 eggs
2 spam
3 ham
Untuk mengakses indeks asli yang tidak dibalik, gunakan 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
Saya pikir cara paling elegan adalah mengubah enumerate
dan reversed
menggunakan generator berikut
(-(ri+1), val) for ri, val in enumerate(reversed(foo))
yang menghasilkan kebalikan dari enumerate
iterator
Contoh:
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)))
]
Hasil:
[6, 4, 2]
Jawaban lainnya baik, tetapi jika Anda ingin melakukan gaya daftar List
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])
saya pikir yang satu ini juga cara mudah untuk melakukannya ... baca dari akhir dan terus menurun sampai panjang daftar, karena kita tidak pernah menjalankan indeks "akhir" maka ditambahkan -1 juga
Dengan asumsi tugas adalah untuk menemukan elemen terakhir yang memenuhi beberapa kondisi dalam daftar (yaitu pertama ketika melihat ke belakang), saya mendapatkan nomor berikut:
>>> 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
Jadi, opsi paling jelek xrange(len(xs)-1,-1,-1)
adalah yang tercepat.