@kdlannoy Według strony, do której link znajduje się w odpowiedzi, „W porównaniu do rozszerzonego krojenia, takiego jak zakres (1,4) [:: - 1], reverse () jest łatwiejszy do odczytania, działa szybciej i zużywa znacznie mniej pamięci. „
Jim Oldfield,
5
Podczas testowania wycinanie było około dwa razy szybsze (podczas odwracania listy 10k elementów i tworzenia z niej listy). Nie testowałem jednak zużycia pamięci. reversemoże być szybszy, jeśli później nie będziesz musiał przesyłać do listy.
Dakkaron
5
warto zauważyć, że nie jest to to samo co rewers ([1,2,3]), nb „d” na końcu… co jest jedną z pozostałych odpowiedzi poniżej, która robi to w miejscu, podczas gdy zwraca iterator.
Luciano,
14
Dlaczego warto korzystać reversed()zamiast krojenia? Przeczytaj Zen Pythona, zasada nr 7: Liczy się czytelność!
Działa z dowolnymi listami interaktywnymi, nie tylko. Wadą jest to, że nie ma go na miejscu.
Szwajcarski
6
@ Tymczasowo zwraca wycinek, więc nie zmienia faktycznej zawartości listy
fortran
12
Odwrócone @lunixbochs zwraca iterator, a nie listę w Pythonie 3.
Szwajcarski
2
chyba że naturalnie odpowiednio zamknięte w tablicy
Einar Petersen
2
Zgadzam się z @Swiss. +1, ponieważ pytanie brzmiało : muszę mieć elementy tablicy, ale od końca do początku. - reversedzwraca listreverseiteratorobiekt (Python 2.7.x), który następnie musi być iterowany - odwrotne krojenie zwraca odwróconą listę / krotkę / str (w zależności od tego, co kroimy). @Einar Petersen, który odwraca ciąg, więc wynik jest poprawny. Spróbuj: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,
367
>>> L =[0,10,20,40]>>> L.reverse()>>> L
[40,20,10,0]
Używanie krojenia, np. Tablica = tablica [:: - 1], jest zgrabną sztuczką i bardzo pytoniczną, ale może być nieco niejasne dla początkujących. Korzystanie z metody reverse () jest dobrym sposobem na codzienne kodowanie, ponieważ jest łatwe do odczytania.
Jednak jeśli musisz odwrócić listę na miejscu, tak jak w pytaniu podczas rozmowy kwalifikacyjnej, prawdopodobnie nie będziesz w stanie korzystać z wbudowanych metod takich jak te. Ankieter będzie przyglądał się raczej podejściu do problemu niż głębokości wiedzy w języku Python, wymagane jest podejście algorytmiczne. Poniższy przykład z klasyczną zamianą może być jednym ze sposobów:
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]
Zauważ, że to nie będzie działać na Tuple lub sekwencjach ciągów, ponieważ ciągi i krotki są niezmienne, tzn. Nie można w nich pisać, aby zmieniać elementy.
Klasyczną zamianę można wykonać lst[hiindex], lst[i] = lst[i], lst[hiindex], jak sądzę ... ;-)
Samoth,
@Samoth Ta składnia nie jest tak jasna, a zachowanie nie jest do końca oczywiste. Wyraźne kroki mają większy sens.
Anthony
dlaczego ludzie mówią, że rzeczy takie jak tablica [:: - 1] są pytoniczne? Python zen uczy nas, że jawne jest lepsze niż niejawne i liczy się czytelność. Takie rzeczy w ogóle nie są jednoznaczne i czytelne.
k4ppa
1
@ k4ppa: array[::-1]jest doskonale czytelny i całkowicie wyraźny, jeśli znasz Pythona . „Czytelny” nie oznacza „ktoś, kto nigdy wcześniej nie korzystał z krojenia Pythona, musi być w stanie go przeczytać”; [::-1]plaster cofania jest śmiesznie wspólny idiom w Pythonie (spotkasz ją w istniejący kod cały czas), i jest doskonale czytelny , jeśli regularnie używać Pythona . Jasne first10 = [], for i in range(10): first10.append(array[i])jest jasne i wyraźne, ale to nie czyni to lepiej niż first10 = array[:10].
ShadowRanger
19
Uważam (w przeciwieństwie do innych sugestii), że l.reverse() jest to zdecydowanie najszybszy sposób na odwrócenie długiej listy w Pythonie 3 i 2. Byłbym zainteresowany dowiedzieć się, czy inni mogą odtworzyć te czasy.
l[::-1]jest prawdopodobnie wolniejszy, ponieważ kopiuje listę przed jej cofnięciem. Dodanie list()wywołania wokół iteratora wykonane przez reversed(l)musi dodać trochę narzutu. Oczywiście, jeśli chcesz kopię listy lub iteratora, użyj tych odpowiednich metod, ale jeśli chcesz tylko odwrócić listę, l.reverse()wydaje się to najszybszym sposobem.
Funkcje
def rev_list1(l):return l[::-1]def rev_list2(l):return list(reversed(l))def rev_list3(l):
l.reverse()return l
list.reversejest najszybszy, ponieważ odwraca się na miejscu
warvariuc
Twoja poprawa list.reverse()jest najszybsza, ale penalizujesz reversed(co jest najlepiej stosowane, gdy nie chcesz nowego list, tylko w celu iteracji istniejącego listw odwrotnej kolejności bez mutowania oryginału) i wycinka (co również pozwala uniknąć mutacji oryginału listi jest zwykle szybszy niż reversedwtedy, gdy dane wejściowe są małe). Tak, jeśli kopia nie jest potrzebna, wszystko, co kopiuje, jest droższe, ale przez większość czasu nie chcesz mutować oryginalnej wartości.
ShadowRanger
Wygląda na to, że reversednadal przegrywalist.reverse() , ale biorąc pod uwagę, że nie powoduje to mutacji danych wejściowych list, w wielu przypadkach jest lepiej. Strata za reversedjest niewielka (~ 1/6 dłuższa niż list.reverse()).
Podsumowanie metod z wyjaśnieniami i wynikami czasowymi
Istnieje kilka dobrych odpowiedzi, ale rozłożone i większość nie wskazuje na zasadnicze różnice każdego podejścia.
Ogólnie rzecz biorąc, lepiej jest używać wbudowanych funkcji / metod do odwracania, tak jak w przypadku dowolnej funkcji. W tym przypadku są one około 2 do 8 razy szybsze na krótkich listach (10 pozycji) i do ~ 300 + szybciej na długich listach w porównaniu do ręcznie utworzonych metod indeksowania. Ma to sens, ponieważ specjaliści je tworzą, analizują i optymalizują. Są również mniej podatne na wady i częściej radzą sobie z skrzynkami na krawędziach i narożnikach.
Zastanów się także, czy chcesz:
Odwróć istniejącą listę w miejscu
Najlepszym rozwiązaniem jest metoda `object.reverse () '
Utwórz iterator odwrotnej strony listy (ponieważ zamierzasz podać go do pętli for, generatora itp.)
Najlepszym rozwiązaniem jest „odwrócony (obiekt)”, który tworzy iterator
lub utwórz kompletną kopię w odwrotnej kolejności
Najlepszym rozwiązaniem jest użycie plasterków o rozmiarze kroku -1: object[::-1]
Skrypt testowy
Oto początek mojego skryptu testowego dla omawianych metod. Umieść wszystkie fragmenty kodu w tej odpowiedzi razem, aby utworzyć skrypt, który będzie uruchamiał różne sposoby odwracania listy i czasu każdego z nich (dane wyjściowe pokazano w ostatniej sekcji).
from timeit import timeit
from copy import copy
def time_str_ms(t):return'{0:8.2f} ms'.format(t *1000)
Metoda 1: Odwróć miejsce za pomocą obj.reverse ()
Jeśli celem jest tylko odwrócenie kolejności elementów na istniejącej liście, bez zapętlania ich lub uzyskiwania kopii do pracy, użyj <list>.reverse()funkcji. Uruchom to bezpośrednio na obiekcie listy, a kolejność wszystkich elementów zostanie odwrócona:
Zwróć uwagę, że następujące czynności odwrócą podaną pierwotną zmienną, nawet jeśli zwróci ona również odwróconą listę. tzn. możesz utworzyć kopię za pomocą tej funkcji wyjściowej. Zwykle nie zrobiłbyś dla tego funkcji, ale zrobiłem to, aby użyć kodu czasowego na końcu.
Przetestujemy wydajność tych dwóch sposobów - najpierw wystarczy cofnąć listę w miejscu (zmienia oryginalną listę), a następnie skopiować listę i odwrócić ją później.
def rev_in_place(mylist):
mylist.reverse()return mylist
def rev_copy_reverse(mylist):
a = copy(mylist)
a.reverse()return a
Metoda 2: Odwróć listę przy użyciu plasterków obj[::-1]
Wbudowana metoda wycinania indeksu pozwala wykonać kopię części dowolnego indeksowanego obiektu.
Nie wpływa na oryginalny obiekt
Tworzy pełną listę, a nie iterator
Składnia generyczny jest: <object>[first_index:last_index:step]. Aby wykorzystać krojenie do utworzenia prostej odwróconej listy, użyj:<list>[::-1] . Pozostawienie opcji pustej powoduje ustawienie domyślnych wartości pierwszego i ostatniego elementu obiektu (odwrócone, jeśli wielkość kroku jest ujemna).
Indeksowanie pozwala na użycie liczb ujemnych, które liczą się od końca indeksu obiektu do tyłu (tj. -2 jest przedostatnim elementem). Gdy rozmiar kroku jest ujemny, rozpocznie się od ostatniego elementu i indeksuje wstecz o tę kwotę. Istnieje pewna logika początkowa, która została zoptymalizowana.
def rev_slice(mylist):
a = mylist[::-1]return a
Metoda 3: Odwróć listę za pomocą reversed(obj)funkcji iteratora
Istnieje reversed(indexed_object)funkcja:
To tworzy iterator indeksu wstecznego, a nie listę. Świetne, jeśli podajesz go do pętli, aby uzyskać lepszą wydajność na dużych listach
Tworzy to kopię i nie wpływa na oryginalny obiekt
Przetestuj zarówno z surowym iteratorem, jak i tworząc listę z iteratora.
def reversed_iterator(mylist):
a = reversed(mylist)return a
def reversed_with_list(mylist):
a = list(reversed(mylist))return a
Metoda 4: Odwróć listę z indeksowaniem niestandardowym / ręcznym
Jak pokaże czas, tworzenie własnych metod indeksowania jest złym pomysłem. Użyj wbudowanych metod, chyba że musisz zrobić coś naprawdę niestandardowego.
To powiedziawszy, nie ma ogromnej kary przy mniejszych rozmiarach list, ale kiedy powiększysz ją, kara staje się ogromna. Jestem pewien, że mój poniższy kod może zostać zoptymalizowany, ale będę trzymać się wbudowanych metod.
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
Czas każdej metody
Poniżej znajduje się reszta skryptu opisująca czas każdej metody cofania. Pokazuje, że cofanie w miejscu obj.reverse()i tworzenie reversed(obj)iteratora jest zawsze najszybsze, a użycie wycinków jest najszybszym sposobem na utworzenie kopii.
Udowadnia także, że nie musisz próbować tworzyć tego samodzielnie, chyba że musisz!
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))
Wyniki pomiaru czasu
Wyniki pokazują, że skalowanie działa najlepiej z wbudowanymi metodami najlepiej dopasowanymi do danego zadania. Innymi słowy, wraz ze wzrostem liczby elementów obiektowych wbudowane metody zaczynają osiągać znacznie lepsze wyniki wydajności.
Lepiej jest też użyć najlepszej wbudowanej metody, która bezpośrednio osiąga to, czego potrzebujesz, niż łączyć rzeczy razem. tzn. dzielenie jest najlepsze, jeśli potrzebujesz kopii odwróconej listy - jest szybsze niż tworzenie listy z reversed()funkcji i szybsze niż tworzenie kopii listy, a następnie robienie w miejscu obj.reverse(). Ale jeśli jedna z tych metod jest naprawdę wszystkim, czego potrzebujesz, są one szybsze, ale nigdy więcej niż dwukrotnie. Tymczasem - niestandardowe, ręczne metody mogą zająć rząd wielkości dłużej, szczególnie w przypadku bardzo dużych list.
Do skalowania, z listą 1000 elementów, reversed(<list>) wywołanie funkcji zajmuje ~ 30 ms, aby ustawić iterator, odwrócenie w miejscu zajmuje tylko ~ 55 ms, przy użyciu metody wycinania zajmuje ~ 210 ms, aby utworzyć kopię pełnej odwróconej listy, ale najszybsza metoda ręczna, jaką zrobiłem, zajęła ~ 8400 ms !!
Z 2 pozycjami na liście:
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]
Z 10 pozycji na liście:
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]
I z 1000 pozycji na liście:
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
Wykorzystanie starej logiki szkolnej do ćwiczenia wywiadów.
Zamiana liczb od przodu do tyłu. Używanie dwóch wskaźnikówindex[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]
Ściśle mówiąc, pytanie nie dotyczy tego, jak zwrócić listę w odwrotnej kolejności, ale jak odwrócić listę z przykładową nazwą listy array.
Aby odwrócić listę o nazwie "array"use array.reverse().
Niezwykle przydatna metoda wycinania, jak opisano, może być również użyta do odwrócenia listy w miejscu, definiując listę jako plastry modyfikacji samego siebie array = array[::-1].
Przy minimalnej liczbie wbudowanych funkcji, przy założeniu, że są to ustawienia wywiadu
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)
Zawsze możesz traktować listę jak stos, po prostu usuwając elementy z góry stosu z tylnego końca listy. W ten sposób wykorzystujesz cechy pierwszego i ostatniego stosu. Oczywiście konsumujesz pierwszą tablicę. Podoba mi się ta metoda, ponieważ jest dość intuicyjna, ponieważ widzisz, że jedna lista jest konsumowana z zaplecza, podczas gdy druga jest budowana z interfejsu.
>>> l =[1,2,3,4,5,6]; nl=[]>>>while l:
nl.append(l.pop())>>>print nl
[6,5,4,3,2,1]
Oto sposób leniwej oceny odwrotności za pomocą generatora :
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
Korzystanie z wbudowanej funkcji: reversed_array = array.reverse()
Trzecia funkcja faktycznie odwróciła obiekt listy na miejscu. Oznacza to, że nie zachowuje się kopii nieskazitelnych danych. To dobre podejście, jeśli nie chcesz zachować starej wersji. Ale nie wydaje się być rozwiązaniem, jeśli chcesz mieć nieskazitelną i odwróconą wersję.
To rozwiązanie jest około 4,5 tys. Razy wolniejsze niż l[::-1], a jednocześnie znacznie mniej czytelne. Programowanie funkcjonalne w Pythonie jest niestety dość powolne.
reverse
może być szybszy, jeśli później nie będziesz musiał przesyłać do listy.reversed()
zamiast krojenia? Przeczytaj Zen Pythona, zasada nr 7: Liczy się czytelność!Rozszerzona składnia wycinka jest dobrze wyjaśniona w Python Co nowego pozycja do wydania
2.3.5
Na specjalne życzenie w komentarzu jest to najnowsza dokumentacja wycinka .
źródło
reversed
zwracalistreverseiterator
obiekt (Python 2.7.x), który następnie musi być iterowany - odwrotne krojenie zwraca odwróconą listę / krotkę / str (w zależności od tego, co kroimy). @Einar Petersen, który odwraca ciąg, więc wynik jest poprawny. Spróbuj: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]
Lub
źródło
L=L[::-1]
odwrócenie listy, w przeciwnym razie zwracane są tylko wartości w odwrotnej kolejnościb = l[-n:] b.reverse() l = b + l[:len(l) - n]
Jest to powielenie listy:
Ma to na celu odwrócenie listy w miejscu:
źródło
Myślę, że najlepszym sposobem na odwrócenie listy w Pythonie jest:
Zadanie zostało wykonane, a teraz masz odwróconą listę.
źródło
Aby cofnąć tę samą listę, użyj:
Aby przypisać listę odwróconą do innej listy, użyj:
źródło
Używanie krojenia, np. Tablica = tablica [:: - 1], jest zgrabną sztuczką i bardzo pytoniczną, ale może być nieco niejasne dla początkujących. Korzystanie z metody reverse () jest dobrym sposobem na codzienne kodowanie, ponieważ jest łatwe do odczytania.
Jednak jeśli musisz odwrócić listę na miejscu, tak jak w pytaniu podczas rozmowy kwalifikacyjnej, prawdopodobnie nie będziesz w stanie korzystać z wbudowanych metod takich jak te. Ankieter będzie przyglądał się raczej podejściu do problemu niż głębokości wiedzy w języku Python, wymagane jest podejście algorytmiczne. Poniższy przykład z klasyczną zamianą może być jednym ze sposobów:
Zauważ, że to nie będzie działać na Tuple lub sekwencjach ciągów, ponieważ ciągi i krotki są niezmienne, tzn. Nie można w nich pisać, aby zmieniać elementy.
źródło
lst[hiindex], lst[i] = lst[i], lst[hiindex]
, jak sądzę ... ;-)array[::-1]
jest doskonale czytelny i całkowicie wyraźny, jeśli znasz Pythona . „Czytelny” nie oznacza „ktoś, kto nigdy wcześniej nie korzystał z krojenia Pythona, musi być w stanie go przeczytać”;[::-1]
plaster cofania jest śmiesznie wspólny idiom w Pythonie (spotkasz ją w istniejący kod cały czas), i jest doskonale czytelny , jeśli regularnie używać Pythona . Jasnefirst10 = []
,for i in range(10): first10.append(array[i])
jest jasne i wyraźne, ale to nie czyni to lepiej niżfirst10 = array[:10]
.Uważam (w przeciwieństwie do innych sugestii), że
l.reverse()
jest to zdecydowanie najszybszy sposób na odwrócenie długiej listy w Pythonie 3 i 2. Byłbym zainteresowany dowiedzieć się, czy inni mogą odtworzyć te czasy.l[::-1]
jest prawdopodobnie wolniejszy, ponieważ kopiuje listę przed jej cofnięciem. Dodanielist()
wywołania wokół iteratora wykonane przezreversed(l)
musi dodać trochę narzutu. Oczywiście, jeśli chcesz kopię listy lub iteratora, użyj tych odpowiednich metod, ale jeśli chcesz tylko odwrócić listę,l.reverse()
wydaje się to najszybszym sposobem.Funkcje
Lista
Czasy Python 3.5
Czasy Python 2.7
źródło
list.reverse
jest najszybszy, ponieważ odwraca się na miejsculist.reverse()
jest najszybsza, ale penalizujeszreversed
(co jest najlepiej stosowane, gdy nie chcesz nowegolist
, tylko w celu iteracji istniejącegolist
w odwrotnej kolejności bez mutowania oryginału) i wycinka (co również pozwala uniknąć mutacji oryginałulist
i jest zwykle szybszy niżreversed
wtedy, gdy dane wejściowe są małe). Tak, jeśli kopia nie jest potrzebna, wszystko, co kopiuje, jest droższe, ale przez większość czasu nie chcesz mutować oryginalnej wartości.reversed
nadal przegrywalist.reverse()
, ale biorąc pod uwagę, że nie powoduje to mutacji danych wejściowychlist
, w wielu przypadkach jest lepiej. Strata zareversed
jest niewielka (~ 1/6 dłuższa niżlist.reverse()
).źródło
Z
reversed
ilist
:źródło
źródło
Użycie odwróconej (tablicy) byłoby prawdopodobnie najlepszą trasą.
Jeśli musisz zrozumieć, jak można to zaimplementować bez korzystania z wbudowanego
reversed
.Powinno to zająć czas O (N).
źródło
Jeśli chcesz przechowywać elementy listy odwróconej w innej zmiennej, możesz użyć
revArray = array[::-1]
lubrevArray = list(reversed(array))
.Ale pierwszy wariant jest nieco szybszy:
Wynik:
źródło
timeit
.WARTOŚCI ORGANIZACYJNE:
W Pythonie także kolejnością list można manipulować sortowaniem , organizując zmienne w kolejności numerycznej / alfabetycznej:
Tymczasowo:
Stały:
Możesz sortować z flagą „reverse = True” :
BEZ ORGANIZACJI
Może nie chcesz sortować wartości, a jedynie odwracać wartości. Następnie możemy to zrobić w następujący sposób:
** Liczby mają pierwszeństwo przed alfabetem w kolejności wyświetlania. Organizacja wartości w języku Python jest niesamowita.
źródło
Podsumowanie metod z wyjaśnieniami i wynikami czasowymi
Istnieje kilka dobrych odpowiedzi, ale rozłożone i większość nie wskazuje na zasadnicze różnice każdego podejścia.
Ogólnie rzecz biorąc, lepiej jest używać wbudowanych funkcji / metod do odwracania, tak jak w przypadku dowolnej funkcji. W tym przypadku są one około 2 do 8 razy szybsze na krótkich listach (10 pozycji) i do ~ 300 + szybciej na długich listach w porównaniu do ręcznie utworzonych metod indeksowania. Ma to sens, ponieważ specjaliści je tworzą, analizują i optymalizują. Są również mniej podatne na wady i częściej radzą sobie z skrzynkami na krawędziach i narożnikach.
Zastanów się także, czy chcesz:
object[::-1]
Skrypt testowy
Oto początek mojego skryptu testowego dla omawianych metod. Umieść wszystkie fragmenty kodu w tej odpowiedzi razem, aby utworzyć skrypt, który będzie uruchamiał różne sposoby odwracania listy i czasu każdego z nich (dane wyjściowe pokazano w ostatniej sekcji).
Metoda 1: Odwróć miejsce za pomocą obj.reverse ()
Jeśli celem jest tylko odwrócenie kolejności elementów na istniejącej liście, bez zapętlania ich lub uzyskiwania kopii do pracy, użyj
<list>.reverse()
funkcji. Uruchom to bezpośrednio na obiekcie listy, a kolejność wszystkich elementów zostanie odwrócona:Zwróć uwagę, że następujące czynności odwrócą podaną pierwotną zmienną, nawet jeśli zwróci ona również odwróconą listę. tzn. możesz utworzyć kopię za pomocą tej funkcji wyjściowej. Zwykle nie zrobiłbyś dla tego funkcji, ale zrobiłem to, aby użyć kodu czasowego na końcu.
Przetestujemy wydajność tych dwóch sposobów - najpierw wystarczy cofnąć listę w miejscu (zmienia oryginalną listę), a następnie skopiować listę i odwrócić ją później.
Metoda 2: Odwróć listę przy użyciu plasterków
obj[::-1]
Wbudowana metoda wycinania indeksu pozwala wykonać kopię części dowolnego indeksowanego obiektu.
Składnia generyczny jest:
<object>[first_index:last_index:step]
. Aby wykorzystać krojenie do utworzenia prostej odwróconej listy, użyj:<list>[::-1]
. Pozostawienie opcji pustej powoduje ustawienie domyślnych wartości pierwszego i ostatniego elementu obiektu (odwrócone, jeśli wielkość kroku jest ujemna).Indeksowanie pozwala na użycie liczb ujemnych, które liczą się od końca indeksu obiektu do tyłu (tj. -2 jest przedostatnim elementem). Gdy rozmiar kroku jest ujemny, rozpocznie się od ostatniego elementu i indeksuje wstecz o tę kwotę. Istnieje pewna logika początkowa, która została zoptymalizowana.
Metoda 3: Odwróć listę za pomocą
reversed(obj)
funkcji iteratoraIstnieje
reversed(indexed_object)
funkcja:Przetestuj zarówno z surowym iteratorem, jak i tworząc listę z iteratora.
Metoda 4: Odwróć listę z indeksowaniem niestandardowym / ręcznym
Jak pokaże czas, tworzenie własnych metod indeksowania jest złym pomysłem. Użyj wbudowanych metod, chyba że musisz zrobić coś naprawdę niestandardowego.
To powiedziawszy, nie ma ogromnej kary przy mniejszych rozmiarach list, ale kiedy powiększysz ją, kara staje się ogromna. Jestem pewien, że mój poniższy kod może zostać zoptymalizowany, ale będę trzymać się wbudowanych metod.
Czas każdej metody
Poniżej znajduje się reszta skryptu opisująca czas każdej metody cofania. Pokazuje, że cofanie w miejscu
obj.reverse()
i tworzeniereversed(obj)
iteratora jest zawsze najszybsze, a użycie wycinków jest najszybszym sposobem na utworzenie kopii.Udowadnia także, że nie musisz próbować tworzyć tego samodzielnie, chyba że musisz!
Wyniki pomiaru czasu
Wyniki pokazują, że skalowanie działa najlepiej z wbudowanymi metodami najlepiej dopasowanymi do danego zadania. Innymi słowy, wraz ze wzrostem liczby elementów obiektowych wbudowane metody zaczynają osiągać znacznie lepsze wyniki wydajności.
Lepiej jest też użyć najlepszej wbudowanej metody, która bezpośrednio osiąga to, czego potrzebujesz, niż łączyć rzeczy razem. tzn. dzielenie jest najlepsze, jeśli potrzebujesz kopii odwróconej listy - jest szybsze niż tworzenie listy z
reversed()
funkcji i szybsze niż tworzenie kopii listy, a następnie robienie w miejscuobj.reverse()
. Ale jeśli jedna z tych metod jest naprawdę wszystkim, czego potrzebujesz, są one szybsze, ale nigdy więcej niż dwukrotnie. Tymczasem - niestandardowe, ręczne metody mogą zająć rząd wielkości dłużej, szczególnie w przypadku bardzo dużych list.Do skalowania, z listą 1000 elementów,
reversed(<list>)
wywołanie funkcji zajmuje ~ 30 ms, aby ustawić iterator, odwrócenie w miejscu zajmuje tylko ~ 55 ms, przy użyciu metody wycinania zajmuje ~ 210 ms, aby utworzyć kopię pełnej odwróconej listy, ale najszybsza metoda ręczna, jaką zrobiłem, zajęła ~ 8400 ms !!Z 2 pozycjami na liście:
Z 10 pozycji na liście:
I z 1000 pozycji na liście:
źródło
Używając logiki
Wykorzystanie starej logiki szkolnej do ćwiczenia wywiadów.
źródło
Możesz także użyć bitowego uzupełnienia indeksu tablicy, aby przechodzić przez tablicę w odwrotnej kolejności:
Cokolwiek robisz, nie rób tego w ten sposób.
źródło
Użyj rozumienia listy:
źródło
Innym rozwiązaniem byłoby użycie do tego numpy.flip
źródło
Ściśle mówiąc, pytanie nie dotyczy tego, jak zwrócić listę w odwrotnej kolejności, ale jak odwrócić listę z przykładową nazwą listy
array
.Aby odwrócić listę o nazwie
"array"
usearray.reverse()
.Niezwykle przydatna metoda wycinania, jak opisano, może być również użyta do odwrócenia listy w miejscu, definiując listę jako plastry modyfikacji samego siebie
array = array[::-1]
.źródło
array[:] = array[::-1]
źródło
Przy minimalnej liczbie wbudowanych funkcji, przy założeniu, że są to ustawienia wywiadu
źródło
Najbardziej bezpośrednim tłumaczeniem twojego wymagania na Python jest ta
for
instrukcja:Jest to dość tajemnicze, ale może być przydatne.
źródło
źródło
//
operatorem podziału podłogi.Zawsze możesz traktować listę jak stos, po prostu usuwając elementy z góry stosu z tylnego końca listy. W ten sposób wykorzystujesz cechy pierwszego i ostatniego stosu. Oczywiście konsumujesz pierwszą tablicę. Podoba mi się ta metoda, ponieważ jest dość intuicyjna, ponieważ widzisz, że jedna lista jest konsumowana z zaplecza, podczas gdy druga jest budowana z interfejsu.
źródło
źródło
posługiwać się
źródło
Oto sposób leniwej oceny odwrotności za pomocą generatora :
Teraz powtarzaj w następujący sposób:
Jeśli potrzebujesz listy:
źródło
Istnieją 3 metody uzyskania odwróconej listy:
Metoda krojenia 1:
reversed_array = array[-1::-1]
Metoda krojenia 2:
reversed_array2 = array[::-1]
Korzystanie z wbudowanej funkcji:
reversed_array = array.reverse()
Trzecia funkcja faktycznie odwróciła obiekt listy na miejscu. Oznacza to, że nie zachowuje się kopii nieskazitelnych danych. To dobre podejście, jeśli nie chcesz zachować starej wersji. Ale nie wydaje się być rozwiązaniem, jeśli chcesz mieć nieskazitelną i odwróconą wersję.
źródło
źródło
l[::-1]
, a jednocześnie znacznie mniej czytelne. Programowanie funkcjonalne w Pythonie jest niestety dość powolne.