@ kdlannoy Menurut laman yang ditautkan dalam jawaban, "Dibandingkan dengan pengirisan yang diperpanjang, seperti rentang (1,4) [:: - 1], terbalik () lebih mudah dibaca, berjalan lebih cepat, dan menggunakan memori yang jauh lebih sedikit. "
Jim Oldfield
5
Ketika saya menguji pengirisan ini sekitar dua kali lebih cepat (ketika membalikkan daftar elemen 10k dan membuat daftar darinya). Saya tidak menguji konsumsi memori. reversemungkin lebih cepat, jika Anda tidak perlu melakukan cast to list sesudahnya.
Dakkaron
5
perlu dicatat bahwa ini tidak sama dengan terbalik ([1,2,3]), nb 'd' di akhir ... yang merupakan salah satu jawaban lain di bawah ini, yang melakukan ini di tempat, sedangkan ini mengembalikan sebuah iterator.
Luciano
14
Mengapa menggunakan reversed()bukannya mengiris? Baca Zen Python, aturan nomor 7: Keterbacaan dapat dihitung!
Ini berfungsi untuk setiap interable, bukan hanya daftar. Kerugiannya adalah tidak ada di tempatnya.
Swiss
6
@Tim mengembalikan potongan, jadi tidak mengubah isi daftar sebenarnya
fortran
12
@lunixbochs terbalik mengembalikan iterator dan bukan daftar dengan Python 3.
Swiss
2
kecuali secara alami dikemas dengan baik dalam array
Einar Petersen
2
Saya setuju dengan @Swiss. 1 sejak pertanyaannya adalah saya harus memiliki elemen array tetapi dari akhir hingga awal. - reversedmengembalikan listreverseiteratorobjek (Python 2.7.x), yang kemudian harus diulangi - pembalikan pembalikan mengembalikan daftar / tuple / str terbalik (tergantung pada apa yang Anda slicing). @Einar Petersen yang membalikkan string, sehingga hasilnya benar. Coba:co2=['ae','ad','ac','ab','aa','z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'] >>> co2[::-1]
Aaron Newton
368
>>> L =[0,10,20,40]>>> L.reverse()>>> L
[40,20,10,0]
Menggunakan slicing, misalnya array = array [:: - 1], adalah trik yang rapi dan sangat Pythonic, tetapi mungkin sedikit tidak jelas bagi pemula. Menggunakan metode reverse () adalah cara yang baik untuk melakukan pengkodean sehari-hari karena mudah dibaca.
Namun, jika Anda perlu membalik daftar di tempat seperti dalam pertanyaan wawancara, Anda kemungkinan tidak akan dapat menggunakan metode bawaan seperti ini. Pewawancara akan melihat bagaimana Anda mendekati masalah daripada kedalaman pengetahuan Python, diperlukan pendekatan algoritmik. Contoh berikut, menggunakan swap klasik, mungkin salah satu cara untuk melakukannya: -
def reverse_in_place(lst):# Declare a function
size = len(lst)# Get the length of the sequence
hiindex = size -1
its = size/2# Number of iterations requiredfor i in xrange(0, its):# i is the low index pointer
temp = lst[hiindex]# Perform a classic swap
lst[hiindex]= lst[i]
lst[i]= temp
hiindex -=1# Decrement the high index pointerprint"Done!"# Now test it!!
array =[2,5,8,9,12,19,25,27,32,60,65,1,7,24,124,654]print array # Print the original sequence
reverse_in_place(array)# Call the function passing the listprint array # Print reversed list**The result:**[2,5,8,9,12,19,25,27,32,60,65,1,7,24,124,654]Done![654,124,24,7,1,65,60,32,27,25,19,12,9,8,5,2]
Perhatikan bahwa ini tidak akan berfungsi pada Tuple atau urutan string, karena string dan tuple tidak dapat diubah, yaitu, Anda tidak dapat menulis ke dalamnya untuk mengubah elemen.
Pertukaran klasik dapat dilakukan melalui lst[hiindex], lst[i] = lst[i], lst[hiindex], saya pikir ... ;-)
Samoth
@ Samoth Sintaks itu tidak sejelas dan perilakunya tidak terlalu jelas. Langkah-langkah berbeda lebih masuk akal.
Anthony
mengapa orang mengatakan bahwa hal-hal seperti array [:: - 1] adalah pythonic? Python zen mengajarkan kita bahwa eksplisit lebih baik daripada implisit dan mudah dibaca. Hal-hal seperti itu tidak eksplisit dan tidak bisa dibaca sama sekali.
k4ppa
1
@ k4ppa: array[::-1]sangat mudah dibaca dan sangat eksplisit jika Anda tahu Python . "Dapat dibaca" tidak berarti "seseorang yang belum pernah menggunakan Python slicing sebelumnya harus dapat membacanya"; yang [::-1]slice membalikkan adalah idiom ridiculously umum di Python (Anda akan menemukan dalam kode sepanjang waktu yang ada), dan itu sempurna dibaca jika Anda secara teratur menggunakan Python . Tentu, first10 = [], for i in range(10): first10.append(array[i])jelas dan eksplisit, tapi itu tidak membuatnya lebih baik dari first10 = array[:10].
ShadowRanger
19
Saya menemukan (bertentangan dengan beberapa saran lain) yang l.reverse()sejauh ini merupakan cara tercepat untuk membalik daftar panjang dengan Python 3 dan 2. Saya tertarik untuk mengetahui apakah orang lain dapat meniru timing ini.
l[::-1]mungkin lebih lambat karena menyalin daftar sebelum membalikkannya. Menambahkan list()panggilan di sekitar iterator yang dibuat oleh reversed(l)harus menambahkan beberapa overhead. Tentu saja jika Anda ingin salinan daftar atau iterator maka gunakan metode masing-masing, tetapi jika Anda ingin membalikkan daftar itu makal.reverse() tampaknya menjadi cara tercepat.
Fungsi
def rev_list1(l):return l[::-1]def rev_list2(l):return list(reversed(l))def rev_list3(l):
l.reverse()return l
list.reverseadalah yang tercepat, karena berbalik pada tempatnya
warvariuc
Anda benar list.reverse()paling cepat, tetapi Anda menghukum reversed(yang paling baik digunakan saat Anda tidak menginginkan yang baru list, hanya untuk mengulang yang sudah ada listdalam urutan terbalik tanpa mengubah yang asli), dan slice (yang juga menghindari bermutasi yang asli list, dan biasanya lebih cepat daripada reversedsaat input kecil). Ya, jika Anda tidak memerlukan salinannya, apa pun yang salinannya lebih mahal, tetapi sering kali, Anda tidak ingin mengubah nilai aslinya.
ShadowRanger
Sepertinya reversedmasih kalahlist.reverse() meski begitu, tetapi mengingat tidak mengubah input list, lebih baik dalam banyak kasus. Kerugiannya reversedkecil (~ 1/6 lebih lama dari list.reverse()).
Sedang mencari cara melakukan itu tanpa menggunakan fungsi terbalik. Terima kasih.
Bernard 'Beta Berlin' Parah
Atau untuk membalikkan di tempatnya, gunakan list = list.reverse ()
SimonM
6
Ringkasan Metode dengan Penjelasan dan Hasil Pengaturan Waktu
Ada beberapa jawaban yang baik, tetapi tersebar dan sebagian besar tidak menunjukkan perbedaan mendasar dari setiap pendekatan.
Secara keseluruhan, lebih baik menggunakan fungsi / metode bawaan untuk membalikkan, seperti halnya fungsi apa pun. Dalam hal ini, mereka kira-kira 2 sampai 8 kali lebih cepat pada daftar pendek (10 item), dan hingga ~ 300 + kali lebih cepat pada daftar panjang dibandingkan dengan cara pengindeksan yang dibuat secara manual. Ini masuk akal karena mereka memiliki para ahli yang membuat mereka, pengawasan, dan optimasi. Mereka juga kurang rentan terhadap cacat dan lebih cenderung menangani kasus tepi dan sudut.
Pertimbangkan juga apakah Anda ingin:
Membalikkan daftar yang ada di tempat
Solusi terbaik adalah object.reverse()metode
Buat iterator dari kebalikan dari daftar (karena Anda akan memberinya makan untuk for-loop, generator, dll.)
Solusi terbaik adalah reversed(object)yang menciptakan iterator
atau buat salinan lengkap yang ada dalam urutan terbalik
Solusi terbaik adalah menggunakan irisan dengan ukuran langkah -1: object[::-1]
Skrip Tes
Inilah awal skrip pengujian saya untuk metode yang dibahas. Masukkan semua potongan kode dalam jawaban ini bersama-sama untuk membuat skrip yang akan menjalankan semua cara yang berbeda untuk membalik daftar dan waktu masing-masing (output ditunjukkan pada bagian terakhir).
from timeit import timeit
from copy import copy
def time_str_ms(t):return'{0:8.2f} ms'.format(t *1000)
Metode 1: Membalikkan di tempat dengan obj.reverse ()
Jika tujuannya hanya untuk membalik urutan item dalam daftar yang ada, tanpa mengulanginya atau mendapatkan salinan untuk bekerja dengan, gunakan <list>.reverse() fungsi. Jalankan ini langsung pada objek daftar, dan urutan semua item akan dibalik:
Perhatikan bahwa yang berikut ini akan membalikkan variabel asli yang diberikan, meskipun itu juga mengembalikan daftar terbalik. yaitu Anda dapat membuat salinan dengan menggunakan output fungsi ini. Biasanya, Anda tidak akan membuat fungsi untuk ini, tetapi saya melakukannya untuk menggunakan kode waktu di akhir.
Kami akan menguji kinerja dua cara ini - pertama hanya membalikkan daftar di tempat (mengubah daftar asli), dan kemudian menyalin daftar dan membalikkannya sesudahnya.
def rev_in_place(mylist):
mylist.reverse()return mylist
def rev_copy_reverse(mylist):
a = copy(mylist)
a.reverse()return a
Metode 2: Membalik daftar menggunakan irisan obj[::-1]
Metode pengiris indeks bawaan memungkinkan Anda membuat salinan bagian dari objek yang diindeks.
Itu tidak mempengaruhi objek asli
Itu membangun daftar lengkap, bukan iterator
Sintaks generik adalah: <object>[first_index:last_index:step]. Untuk mengeksploitasi slicing untuk membuat daftar terbalik sederhana, gunakan:<list>[::-1] . Ketika membiarkan opsi kosong, itu menetapkan mereka ke default dari elemen pertama dan terakhir objek (terbalik jika ukuran langkah negatif).
Pengindeksan memungkinkan seseorang untuk menggunakan angka negatif, yang dihitung dari akhir indeks objek mundur (yaitu -2 adalah item kedua ke terakhir). Ketika ukuran langkah negatif, itu akan mulai dengan item terakhir dan indeks mundur dengan jumlah itu. Ada beberapa logika awal-akhir yang terkait dengan ini yang telah dioptimalkan.
def rev_slice(mylist):
a = mylist[::-1]return a
Metode 3: Membalik daftar dengan reversed(obj)fungsi iterator
Ada reversed(indexed_object)fungsi:
Ini menciptakan iterator indeks terbalik, bukan daftar. Sangat bagus jika Anda memasukkannya ke loop untuk kinerja yang lebih baik pada daftar besar
Ini menciptakan salinan dan tidak mempengaruhi objek asli
Uji dengan kedua iterator mentah, dan buat daftar dari iterator.
def reversed_iterator(mylist):
a = reversed(mylist)return a
def reversed_with_list(mylist):
a = list(reversed(mylist))return a
Metode 4: Daftar terbalik dengan pengindeksan Kustom / Manual
Seperti yang ditunjukkan oleh waktu, menciptakan metode pengindeksan Anda sendiri adalah ide yang buruk. Gunakan metode bawaan kecuali Anda perlu melakukan sesuatu yang benar-benar khusus.
Yang mengatakan, tidak ada penalti besar dengan ukuran daftar lebih kecil, tetapi ketika Anda meningkatkan hukuman menjadi luar biasa. Saya yakin kode saya di bawah ini dapat dioptimalkan, tetapi saya akan tetap menggunakan metode bawaan.
def rev_manual_pos_gen(mylist):
max_index = len(mylist)-1return[ mylist[max_index - index]for index in range(len(mylist))]def rev_manual_neg_gen(mylist):## index is 0 to 9, but we need -1 to -10return[ mylist[-index-1]for index in range(len(mylist))]def rev_manual_index_loop(mylist):
a =[]
reverse_index = len(mylist)-1for index in range(len(mylist)):
a.append(mylist[reverse_index - index])return a
def rev_manual_loop(mylist):
a =[]
reverse_index = len(mylist)for index, _ in enumerate(mylist):
reverse_index -=1
a.append(mylist[reverse_index])return a
Pengaturan waktu setiap metode
Berikut ini adalah sisa skrip untuk menentukan waktu setiap metode pembalikan. Ini menunjukkan pembalikan di tempat dengan obj.reverse()dan menciptakan reversed(obj)iterator selalu yang tercepat, sementara menggunakan irisan adalah cara tercepat untuk membuat salinan.
Itu juga terbukti tidak mencoba menciptakan cara melakukannya sendiri kecuali Anda harus!
loops_to_test =100000
number_of_items =10
list_to_reverse = list(range(number_of_items))if number_of_items <15:print("a: {}".format(list_to_reverse))print('Loops: {:,}'.format(loops_to_test))# List of the functions we want to test with the timer, in print order
fcns =[rev_in_place, reversed_iterator, rev_slice, rev_copy_reverse,
reversed_with_list, rev_manual_pos_gen, rev_manual_neg_gen,
rev_manual_index_loop, rev_manual_loop]
max_name_string = max([ len(fcn.__name__)for fcn in fcns ])for fcn in fcns:
a = copy(list_to_reverse)# copy to start fresh each loop
out_str =' | out = {}'.format(fcn(a))if number_of_items <15else''# Time in ms for the given # of loops on this fcn
time_str = time_str_ms(timeit(lambda: fcn(a), number=loops_to_test))# Get the output string for this function
fcn_str ='{}(a):'.format(fcn.__name__)# Add the correct string length to accommodate the maximum fcn name
format_str ='{{fx:{}s}} {{time}}{{rev}}'.format(max_name_string +4)print(format_str.format(fx=fcn_str, time=time_str, rev=out_str))
Hasil Pengaturan Waktu
Hasil menunjukkan bahwa penskalaan bekerja paling baik dengan metode bawaan yang paling cocok untuk tugas yang diberikan. Dengan kata lain, dengan meningkatnya jumlah elemen objek, metode bawaan mulai memiliki hasil kinerja yang jauh lebih unggul.
Anda juga lebih baik menggunakan metode bawaan terbaik yang secara langsung mencapai apa yang Anda butuhkan daripada merangkai semuanya. yaitu mengiris adalah yang terbaik jika Anda membutuhkan salinan daftar terbalik - itu lebih cepat daripada membuat daftar dari reversed()fungsi, dan lebih cepat daripada membuat salinan daftar dan kemudian melakukan di tempatobj.reverse() . Tetapi jika salah satu dari metode itu benar-benar yang Anda butuhkan, mereka lebih cepat, tetapi tidak pernah lebih dari dua kali lipat kecepatan. Sementara itu - kustom, metode manual dapat mengambil pesanan lebih besar, terutama dengan daftar yang sangat besar.
Untuk penskalaan, dengan daftar 1000 item, reversed(<list>)pemanggilan fungsi membutuhkan ~ 30 ms untuk mengatur iterator, pembalikan di tempat hanya membutuhkan ~ 55 ms, menggunakan metode slice membutuhkan ~ 210 ms untuk membuat salinan dari daftar yang dibalik sepenuhnya, tetapi metode manual tercepat yang saya buat mengambil ~ 8400 ms !!
Dengan 2 item dalam daftar:
a:[0,1]Loops:100,000
rev_in_place(a):24.70 ms | out =[1,0]
reversed_iterator(a):30.48 ms | out =<list_reverseiterator object at 0x0000020242580408>
rev_slice(a):31.65 ms | out =[1,0]
rev_copy_reverse(a):63.42 ms | out =[1,0]
reversed_with_list(a):48.65 ms | out =[1,0]
rev_manual_pos_gen(a):98.94 ms | out =[1,0]
rev_manual_neg_gen(a):88.11 ms | out =[1,0]
rev_manual_index_loop(a):87.23 ms | out =[1,0]
rev_manual_loop(a):79.24 ms | out =[1,0]
Dengan 10 item dalam daftar:
rev_in_place(a):23.39 ms | out =[9,8,7,6,5,4,3,2,1,0]
reversed_iterator(a):30.23 ms | out =<list_reverseiterator object at 0x00000290A3CB0388>
rev_slice(a):36.01 ms | out =[9,8,7,6,5,4,3,2,1,0]
rev_copy_reverse(a):64.67 ms | out =[9,8,7,6,5,4,3,2,1,0]
reversed_with_list(a):50.77 ms | out =[9,8,7,6,5,4,3,2,1,0]
rev_manual_pos_gen(a):162.83 ms | out =[9,8,7,6,5,4,3,2,1,0]
rev_manual_neg_gen(a):167.43 ms | out =[9,8,7,6,5,4,3,2,1,0]
rev_manual_index_loop(a):152.04 ms | out =[9,8,7,6,5,4,3,2,1,0]
rev_manual_loop(a):183.01 ms | out =[9,8,7,6,5,4,3,2,1,0]
Dan dengan 1000 item dalam daftar:
rev_in_place(a):56.37 ms
reversed_iterator(a):30.47 ms
rev_slice(a):211.42 ms
rev_copy_reverse(a):295.74 ms
reversed_with_list(a):418.45 ms
rev_manual_pos_gen(a):8410.01 ms
rev_manual_neg_gen(a):11054.84 ms
rev_manual_index_loop(a):10543.11 ms
rev_manual_loop(a):15472.66 ms
Jika Anda ingin menyimpan elemen daftar terbalik di beberapa variabel lain, maka Anda bisa menggunakan revArray = array[::-1]atau revArray = list(reversed(array)).
Tetapi varian pertama sedikit lebih cepat:
z = range(1000000)
startTimeTic = time.time()
y = z[::-1]print("Time: %s s"%(time.time()- startTimeTic))
f = range(1000000)
startTimeTic = time.time()
g = list(reversed(f))print("Time: %s s"%(time.time()- startTimeTic))
Menggunakan beberapa logika sekolah lama untuk berlatih wawancara.
Menukar angka dari depan ke belakang. Menggunakan dua petunjukindex[0] and index[last]
def reverse(array):
n = array
first =0
last = len(array)-1while first < last:
holder = n[first]
n[first]= n[last]
n[last]= holder
first +=1
last -=1return n
input ->[-1,1,2,3,4,5,6]
output ->[6,1,2,3,4,5,-1]
Jika kita membagi daftar menjadi dua dan menukar yang pertama dengan indeks terakhir dan kompleksitas waktu akan lebih efisien daripada sampel yang terdaftar.
Israel Manzo
3
Anda juga dapat menggunakan komplemen bitwise dari indeks array untuk melangkah melalui array secara terbalik:
>>> array =[0,10,20,40]>>>[array[~i]for i, _ in enumerate(array)][40,20,10,0]
Apa pun yang Anda lakukan, jangan lakukan seperti ini.
Sebenarnya, pertanyaannya bukanlah bagaimana mengembalikan daftar secara terbalik, melainkan bagaimana membalik daftar dengan nama daftar contoh array.
Untuk membalikkan daftar bernama "array"use array.reverse().
Metode irisan yang sangat berguna seperti yang dijelaskan juga dapat digunakan untuk membalik daftar di tempat dengan mendefinisikan daftar sebagai modifikasi irisan itu sendiri menggunakan array = array[::-1].
Dengan jumlah minimum fungsi bawaan, dengan asumsi pengaturan wawancara itu
array =[1,2,3,4,5,6,7,8]
inverse =[]#create container for inverse array
length = len(array)#to iterate later, returns 8
counter = length -1#because the 8th element is on position 7 (as python starts from 0)for i in range(length):
inverse.append(array[counter])
counter -=1print(inverse)
Anda selalu dapat memperlakukan daftar seperti tumpukan hanya dengan memunculkan elemen dari atas tumpukan dari bagian belakang daftar. Dengan begitu Anda memanfaatkan karakteristik tumpukan pertama yang terakhir keluar. Tentu saja Anda mengkonsumsi array 1. Saya suka metode ini karena cukup intuitif karena Anda melihat satu daftar dikonsumsi dari ujung belakang sementara yang lain dibangun dari ujung depan.
>>> l =[1,2,3,4,5,6]; nl=[]>>>while l:
nl.append(l.pop())>>>print nl
[6,5,4,3,2,1]
Berikut cara untuk mengevaluasi kebalikan dari menggunakan generator :
def reverse(seq):for x in range(len(seq),-1,-1):#Iterate through a sequence starting from -1 and increasing by -1.yield seq[x]#Yield a value to the generator
Menggunakan fungsi builtin: reversed_array = array.reverse()
Fungsi ketiga sebenarnya membalikkan objek daftar di tempat. Itu berarti tidak ada salinan data murni dipertahankan. Ini adalah pendekatan yang baik jika Anda tidak ingin mempertahankan versi yang lama. Tetapi sepertinya tidak menjadi solusi jika Anda menginginkan versi yang asli dan terbalik.
Solusi ini sekitar 4,5k kali lebih lambat daripada l[::-1], dan pada saat yang sama jauh lebih mudah terbaca. Pemrograman fungsional dengan Python sayangnya agak lambat.
reverse
mungkin lebih cepat, jika Anda tidak perlu melakukan cast to list sesudahnya.reversed()
bukannya mengiris? Baca Zen Python, aturan nomor 7: Keterbacaan dapat dihitung!Sintaks slice yang diperluas dijelaskan dengan baik dalam Python Entri baru untuk rilis
2.3.5
Dengan permintaan khusus dalam komentar, ini adalah dokumentasi slice terbaru .
sumber
reversed
mengembalikanlistreverseiterator
objek (Python 2.7.x), yang kemudian harus diulangi - pembalikan pembalikan mengembalikan daftar / tuple / str terbalik (tergantung pada apa yang Anda slicing). @Einar Petersen yang membalikkan string, sehingga hasilnya benar. Coba:co2=['ae','ad','ac','ab','aa','z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'] >>> co2[::-1]
Atau
sumber
L=L[::-1]
benar-benar membalik daftar jika tidak Anda hanya mengembalikan nilai secara terbalikb = l[-n:] b.reverse() l = b + l[:len(l) - n]
Ini untuk menggandakan daftar:
Ini untuk membalik daftar di tempat:
sumber
Saya pikir cara terbaik untuk membalik daftar dengan Python adalah dengan melakukan:
Pekerjaan selesai, dan sekarang Anda memiliki daftar terbalik.
sumber
Untuk membalikkan daftar yang sama gunakan:
Untuk menetapkan daftar terbalik ke dalam beberapa daftar lain gunakan:
sumber
Menggunakan slicing, misalnya array = array [:: - 1], adalah trik yang rapi dan sangat Pythonic, tetapi mungkin sedikit tidak jelas bagi pemula. Menggunakan metode reverse () adalah cara yang baik untuk melakukan pengkodean sehari-hari karena mudah dibaca.
Namun, jika Anda perlu membalik daftar di tempat seperti dalam pertanyaan wawancara, Anda kemungkinan tidak akan dapat menggunakan metode bawaan seperti ini. Pewawancara akan melihat bagaimana Anda mendekati masalah daripada kedalaman pengetahuan Python, diperlukan pendekatan algoritmik. Contoh berikut, menggunakan swap klasik, mungkin salah satu cara untuk melakukannya: -
Perhatikan bahwa ini tidak akan berfungsi pada Tuple atau urutan string, karena string dan tuple tidak dapat diubah, yaitu, Anda tidak dapat menulis ke dalamnya untuk mengubah elemen.
sumber
lst[hiindex], lst[i] = lst[i], lst[hiindex]
, saya pikir ... ;-)array[::-1]
sangat mudah dibaca dan sangat eksplisit jika Anda tahu Python . "Dapat dibaca" tidak berarti "seseorang yang belum pernah menggunakan Python slicing sebelumnya harus dapat membacanya"; yang[::-1]
slice membalikkan adalah idiom ridiculously umum di Python (Anda akan menemukan dalam kode sepanjang waktu yang ada), dan itu sempurna dibaca jika Anda secara teratur menggunakan Python . Tentu,first10 = []
,for i in range(10): first10.append(array[i])
jelas dan eksplisit, tapi itu tidak membuatnya lebih baik darifirst10 = array[:10]
.Saya menemukan (bertentangan dengan beberapa saran lain) yang
l.reverse()
sejauh ini merupakan cara tercepat untuk membalik daftar panjang dengan Python 3 dan 2. Saya tertarik untuk mengetahui apakah orang lain dapat meniru timing ini.l[::-1]
mungkin lebih lambat karena menyalin daftar sebelum membalikkannya. Menambahkanlist()
panggilan di sekitar iterator yang dibuat olehreversed(l)
harus menambahkan beberapa overhead. Tentu saja jika Anda ingin salinan daftar atau iterator maka gunakan metode masing-masing, tetapi jika Anda ingin membalikkan daftar itu makal.reverse()
tampaknya menjadi cara tercepat.Fungsi
Daftar
Python 3,5 timing
Pengaturan waktu Python 2.7
sumber
list.reverse
adalah yang tercepat, karena berbalik pada tempatnyalist.reverse()
paling cepat, tetapi Anda menghukumreversed
(yang paling baik digunakan saat Anda tidak menginginkan yang barulist
, hanya untuk mengulang yang sudah adalist
dalam urutan terbalik tanpa mengubah yang asli), dan slice (yang juga menghindari bermutasi yang aslilist
, dan biasanya lebih cepat daripadareversed
saat input kecil). Ya, jika Anda tidak memerlukan salinannya, apa pun yang salinannya lebih mahal, tetapi sering kali, Anda tidak ingin mengubah nilai aslinya.reversed
masih kalahlist.reverse()
meski begitu, tetapi mengingat tidak mengubah inputlist
, lebih baik dalam banyak kasus. Kerugiannyareversed
kecil (~ 1/6 lebih lama darilist.reverse()
).sumber
Dengan
reversed
danlist
:sumber
sumber
Menggunakan terbalik (array) akan menjadi rute terbaik.
Jika Anda perlu memahami bagaimana bisa menerapkan ini tanpa menggunakan bawaan
reversed
.Ini akan membutuhkan waktu O (N).
sumber
Ringkasan Metode dengan Penjelasan dan Hasil Pengaturan Waktu
Ada beberapa jawaban yang baik, tetapi tersebar dan sebagian besar tidak menunjukkan perbedaan mendasar dari setiap pendekatan.
Secara keseluruhan, lebih baik menggunakan fungsi / metode bawaan untuk membalikkan, seperti halnya fungsi apa pun. Dalam hal ini, mereka kira-kira 2 sampai 8 kali lebih cepat pada daftar pendek (10 item), dan hingga ~ 300 + kali lebih cepat pada daftar panjang dibandingkan dengan cara pengindeksan yang dibuat secara manual. Ini masuk akal karena mereka memiliki para ahli yang membuat mereka, pengawasan, dan optimasi. Mereka juga kurang rentan terhadap cacat dan lebih cenderung menangani kasus tepi dan sudut.
Pertimbangkan juga apakah Anda ingin:
object.reverse()
metodereversed(object)
yang menciptakan iteratorobject[::-1]
Skrip Tes
Inilah awal skrip pengujian saya untuk metode yang dibahas. Masukkan semua potongan kode dalam jawaban ini bersama-sama untuk membuat skrip yang akan menjalankan semua cara yang berbeda untuk membalik daftar dan waktu masing-masing (output ditunjukkan pada bagian terakhir).
Metode 1: Membalikkan di tempat dengan obj.reverse ()
Jika tujuannya hanya untuk membalik urutan item dalam daftar yang ada, tanpa mengulanginya atau mendapatkan salinan untuk bekerja dengan, gunakan
<list>.reverse()
fungsi. Jalankan ini langsung pada objek daftar, dan urutan semua item akan dibalik:Perhatikan bahwa yang berikut ini akan membalikkan variabel asli yang diberikan, meskipun itu juga mengembalikan daftar terbalik. yaitu Anda dapat membuat salinan dengan menggunakan output fungsi ini. Biasanya, Anda tidak akan membuat fungsi untuk ini, tetapi saya melakukannya untuk menggunakan kode waktu di akhir.
Kami akan menguji kinerja dua cara ini - pertama hanya membalikkan daftar di tempat (mengubah daftar asli), dan kemudian menyalin daftar dan membalikkannya sesudahnya.
Metode 2: Membalik daftar menggunakan irisan
obj[::-1]
Metode pengiris indeks bawaan memungkinkan Anda membuat salinan bagian dari objek yang diindeks.
Sintaks generik adalah:
<object>[first_index:last_index:step]
. Untuk mengeksploitasi slicing untuk membuat daftar terbalik sederhana, gunakan:<list>[::-1]
. Ketika membiarkan opsi kosong, itu menetapkan mereka ke default dari elemen pertama dan terakhir objek (terbalik jika ukuran langkah negatif).Pengindeksan memungkinkan seseorang untuk menggunakan angka negatif, yang dihitung dari akhir indeks objek mundur (yaitu -2 adalah item kedua ke terakhir). Ketika ukuran langkah negatif, itu akan mulai dengan item terakhir dan indeks mundur dengan jumlah itu. Ada beberapa logika awal-akhir yang terkait dengan ini yang telah dioptimalkan.
Metode 3: Membalik daftar dengan
reversed(obj)
fungsi iteratorAda
reversed(indexed_object)
fungsi:Uji dengan kedua iterator mentah, dan buat daftar dari iterator.
Metode 4: Daftar terbalik dengan pengindeksan Kustom / Manual
Seperti yang ditunjukkan oleh waktu, menciptakan metode pengindeksan Anda sendiri adalah ide yang buruk. Gunakan metode bawaan kecuali Anda perlu melakukan sesuatu yang benar-benar khusus.
Yang mengatakan, tidak ada penalti besar dengan ukuran daftar lebih kecil, tetapi ketika Anda meningkatkan hukuman menjadi luar biasa. Saya yakin kode saya di bawah ini dapat dioptimalkan, tetapi saya akan tetap menggunakan metode bawaan.
Pengaturan waktu setiap metode
Berikut ini adalah sisa skrip untuk menentukan waktu setiap metode pembalikan. Ini menunjukkan pembalikan di tempat dengan
obj.reverse()
dan menciptakanreversed(obj)
iterator selalu yang tercepat, sementara menggunakan irisan adalah cara tercepat untuk membuat salinan.Itu juga terbukti tidak mencoba menciptakan cara melakukannya sendiri kecuali Anda harus!
Hasil Pengaturan Waktu
Hasil menunjukkan bahwa penskalaan bekerja paling baik dengan metode bawaan yang paling cocok untuk tugas yang diberikan. Dengan kata lain, dengan meningkatnya jumlah elemen objek, metode bawaan mulai memiliki hasil kinerja yang jauh lebih unggul.
Anda juga lebih baik menggunakan metode bawaan terbaik yang secara langsung mencapai apa yang Anda butuhkan daripada merangkai semuanya. yaitu mengiris adalah yang terbaik jika Anda membutuhkan salinan daftar terbalik - itu lebih cepat daripada membuat daftar dari
reversed()
fungsi, dan lebih cepat daripada membuat salinan daftar dan kemudian melakukan di tempatobj.reverse()
. Tetapi jika salah satu dari metode itu benar-benar yang Anda butuhkan, mereka lebih cepat, tetapi tidak pernah lebih dari dua kali lipat kecepatan. Sementara itu - kustom, metode manual dapat mengambil pesanan lebih besar, terutama dengan daftar yang sangat besar.Untuk penskalaan, dengan daftar 1000 item,
reversed(<list>)
pemanggilan fungsi membutuhkan ~ 30 ms untuk mengatur iterator, pembalikan di tempat hanya membutuhkan ~ 55 ms, menggunakan metode slice membutuhkan ~ 210 ms untuk membuat salinan dari daftar yang dibalik sepenuhnya, tetapi metode manual tercepat yang saya buat mengambil ~ 8400 ms !!Dengan 2 item dalam daftar:
Dengan 10 item dalam daftar:
Dan dengan 1000 item dalam daftar:
sumber
Jika Anda ingin menyimpan elemen daftar terbalik di beberapa variabel lain, maka Anda bisa menggunakan
revArray = array[::-1]
ataurevArray = list(reversed(array))
.Tetapi varian pertama sedikit lebih cepat:
Keluaran:
sumber
timeit
.NILAI PENGELOLAAN:
Dalam Python, urutan daftar juga dapat dimanipulasi dengan mengurutkan , mengatur variabel Anda dalam urutan numerik / alfabet:
Untuk sementara:
Permanen:
Anda dapat mengurutkan dengan flag "reverse = True" :
TANPA MENGORGANISASI
Mungkin Anda tidak ingin mengurutkan nilai, tetapi hanya membalikkan nilainya. Maka kita bisa melakukannya seperti ini:
** Angka memiliki prioritas di atas alfabet dalam urutan listing. Organisasi nilai-nilai Python mengagumkan.
sumber
Menggunakan beberapa logika
Menggunakan beberapa logika sekolah lama untuk berlatih wawancara.
sumber
Anda juga dapat menggunakan komplemen bitwise dari indeks array untuk melangkah melalui array secara terbalik:
Apa pun yang Anda lakukan, jangan lakukan seperti ini.
sumber
Gunakan pemahaman daftar:
sumber
Solusi lain adalah menggunakan numpy.flip untuk ini
sumber
Sebenarnya, pertanyaannya bukanlah bagaimana mengembalikan daftar secara terbalik, melainkan bagaimana membalik daftar dengan nama daftar contoh
array
.Untuk membalikkan daftar bernama
"array"
usearray.reverse()
.Metode irisan yang sangat berguna seperti yang dijelaskan juga dapat digunakan untuk membalik daftar di tempat dengan mendefinisikan daftar sebagai modifikasi irisan itu sendiri menggunakan
array = array[::-1]
.sumber
array[:] = array[::-1]
sumber
Dengan jumlah minimum fungsi bawaan, dengan asumsi pengaturan wawancara itu
sumber
Terjemahan paling langsung dari persyaratan Anda ke Python adalah
for
pernyataan ini :Ini agak samar tetapi mungkin bermanfaat.
sumber
sumber
//
operator divisi lantai.Anda selalu dapat memperlakukan daftar seperti tumpukan hanya dengan memunculkan elemen dari atas tumpukan dari bagian belakang daftar. Dengan begitu Anda memanfaatkan karakteristik tumpukan pertama yang terakhir keluar. Tentu saja Anda mengkonsumsi array 1. Saya suka metode ini karena cukup intuitif karena Anda melihat satu daftar dikonsumsi dari ujung belakang sementara yang lain dibangun dari ujung depan.
sumber
sumber
menggunakan
sumber
Berikut cara untuk mengevaluasi kebalikan dari menggunakan generator :
Sekarang beralih melalui seperti ini:
Jika Anda membutuhkan daftar:
sumber
Ada 3 metode untuk mendapatkan daftar terbalik:
Metode Mengiris 1:
reversed_array = array[-1::-1]
Metode Mengiris 2:
reversed_array2 = array[::-1]
Menggunakan fungsi builtin:
reversed_array = array.reverse()
Fungsi ketiga sebenarnya membalikkan objek daftar di tempat. Itu berarti tidak ada salinan data murni dipertahankan. Ini adalah pendekatan yang baik jika Anda tidak ingin mempertahankan versi yang lama. Tetapi sepertinya tidak menjadi solusi jika Anda menginginkan versi yang asli dan terbalik.
sumber
sumber
l[::-1]
, dan pada saat yang sama jauh lebih mudah terbaca. Pemrograman fungsional dengan Python sayangnya agak lambat.