Dengan Python, apa cara terbaik untuk membuat daftar baru yang itemnya sama dengan daftar lainnya, tetapi dalam urutan terbalik? (Saya tidak ingin mengubah daftar yang sudah ada.)
Inilah satu solusi yang terpikir oleh saya:
new_list = list(reversed(old_list))
Ini juga memungkinkan untuk menduplikasi old_list
kemudian membalikkan duplikat di tempat:
new_list = list(old_list) # or `new_list = old_list[:]`
new_list.reverse()
Apakah ada opsi yang lebih baik yang saya abaikan? Jika tidak, apakah ada alasan yang memaksa (seperti efisiensi) untuk menggunakan salah satu pendekatan di atas daripada yang lain?
sumber
list(reversed(oldlist))
. Selain kecil mikro-optimasi, apakah ada alasan untuk lebih memilih[::-1]
kereversed()
?reversed
memiliki keuntungan besar ketika Anda tidak membutuhkan daftar tersebut, karena tidak membuang-buang memori atau membangunnya di awal. Tetapi ketika Anda benar- benar membutuhkan daftar tersebut, menggunakan[::-1]
sebagai ganti darilist(reversed())
sama dengan menggunakan a,[listcomp]
bukanlist(genexpr)
.[::-1]
berarti menghapus elemen terakhir dari sebuah daftar, daripada membaliknya.reversed(list)
menyatakan dengan tepat apa yang dilakukannya; itu menjelaskan maksudnya, dalam arti "Eksplisit lebih baik daripada implisit", "Keterbacaan dihitung", dan "Jarang lebih baik daripada padat".Sekarang ayo
timeit
. Petunjuk: Alex[::-1]
tercepat :)$ p -m timeit "ol = [1, 2, 3]; nl = list(reversed(ol))" 100000 loops, best of 3: 2.34 usec per loop $ p -m timeit "ol = [1, 2, 3]; nl = list(ol); nl.reverse();" 1000000 loops, best of 3: 0.686 usec per loop $ p -m timeit "ol = [1, 2, 3]; nl = ol[::-1];" 1000000 loops, best of 3: 0.569 usec per loop $ p -m timeit "ol = [1, 2, 3]; nl = [i for i in reversed(ol)];" 1000000 loops, best of 3: 1.48 usec per loop $ p -m timeit "ol = [1, 2, 3]*1000; nl = list(reversed(ol))" 10000 loops, best of 3: 44.7 usec per loop $ p -m timeit "ol = [1, 2, 3]*1000; nl = list(ol); nl.reverse();" 10000 loops, best of 3: 27.2 usec per loop $ p -m timeit "ol = [1, 2, 3]*1000; nl = ol[::-1];" 10000 loops, best of 3: 24.3 usec per loop $ p -m timeit "ol = [1, 2, 3]*1000; nl = [i for i in reversed(ol)];" 10000 loops, best of 3: 155 usec per loop
Pembaruan: Menambahkan metode komp daftar yang disarankan oleh inspectorG4dget. Saya akan membiarkan hasilnya berbicara sendiri.
sumber
[::-1]
Penyesuaian
Ada baiknya memberikan patokan / penyesuaian dasar untuk perhitungan timeit oleh sdolan yang menunjukkan kinerja 'terbalik' tanpa
list()
konversi yang sering tidak perlu .list()
Operasi ini menambahkan 26 usec tambahan ke runtime dan hanya diperlukan jika iterator tidak dapat diterima.Hasil:
reversed(lst) -- 11.2 usecs list(reversed(lst)) -- 37.1 usecs lst[::-1] -- 23.6 usecs
Perhitungan:
# I ran this set of 100000 and came up with 11.2, twice: python -m timeit "ol = [1, 2, 3]*1000; nl = reversed(ol)" 100000 loops, best of 3: 11.2 usec per loop # This shows the overhead of list() python -m timeit "ol = [1, 2, 3]*1000; nl = list(reversed(ol))" 10000 loops, best of 3: 37.1 usec per loop # This is the result for reverse via -1 step slices python -m timeit "ol = [1, 2, 3]*1000;nl = ol[::-1]" 10000 loops, best of 3: 23.6 usec per loop
Kesimpulan:
Kesimpulan dari pengujian
reversed()
ini lebih cepat daripada potongan[::-1]
dengan 12,4 usecsumber
''.join(reversed(['1','2','3']))
metode slice masih> 30% lebih cepat.