Odpowiedzi:
Możesz użyć do tego reversed
funkcji jako:
>>> array=[0,10,20,40]
>>> for i in reversed(array):
... print(i)
Pamiętaj, że reversed(...)
nie zwraca listy. Możesz uzyskać odwróconą listę używając list(reversed(array))
.
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ść!
>>> L = [0,10,20,40]
>>> L[::-1]
[40, 20, 10, 0]
Rozszerzona składnia wycinka jest dobrze wyjaśniona w Python Co nowego pozycja do wydania2.3.5
Na specjalne życzenie w komentarzu jest to najnowsza dokumentacja wycinka .
reversed
zwraca listreverseiterator
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]
>>> L = [0,10,20,40]
>>> L.reverse()
>>> L
[40, 20, 10, 0]
Lub
>>> L[::-1]
[40, 20, 10, 0]
L=L[::-1]
odwrócenie listy, w przeciwnym razie zwracane są tylko wartości w odwrotnej kolejności
b = l[-n:] b.reverse() l = b + l[:len(l) - n]
Myślę, że najlepszym sposobem na odwrócenie listy w Pythonie jest:
a = [1,2,3,4]
a = a[::-1]
print(a)
>>> [4,3,2,1]
Zadanie zostało wykonane, a teraz masz odwróconą listę.
Aby cofnąć tę samą listę, użyj:
array.reverse()
Aby przypisać listę odwróconą do innej listy, użyj:
newArray = array[::-1]
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 required
for 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 pointer
print "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 list
print 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.
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 . 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]
.
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
Lista
l = list(range(1000000))
Czasy Python 3.5
timeit(lambda: rev_list1(l), number=1000)
# 6.48
timeit(lambda: rev_list2(l), number=1000)
# 7.13
timeit(lambda: rev_list3(l), number=1000)
# 0.44
Czasy Python 2.7
timeit(lambda: rev_list1(l), number=1000)
# 6.76
timeit(lambda: rev_list2(l), number=1000)
# 9.18
timeit(lambda: rev_list3(l), number=1000)
# 0.46
list.reverse
jest najszybszy, ponieważ odwraca się na miejscu
list.reverse()
jest najszybsza, ale penalizujesz reversed
(co jest najlepiej stosowane, gdy nie chcesz nowego list
, tylko w celu iteracji istniejącego list
w odwrotnej kolejności bez mutowania oryginału) i wycinka (co również pozwala uniknąć mutacji oryginału list
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ściowych list
, w wielu przypadkach jest lepiej. Strata za reversed
jest niewielka (~ 1/6 dłuższa niż list.reverse()
).
for x in array[::-1]:
do stuff
>>> list1 = [1,2,3]
>>> reversed_list = list(reversed(list1))
>>> reversed_list
>>> [3, 2, 1]
array=[0,10,20,40]
for e in reversed(array):
print e
Użycie odwróconej (tablicy) byłoby prawdopodobnie najlepszą trasą.
>>> array = [1,2,3,4]
>>> for item in reversed(array):
>>> print item
Jeśli musisz zrozumieć, jak można to zaimplementować bez korzystania z wbudowanego reversed
.
def reverse(a):
midpoint = len(a)/2
for item in a[:midpoint]:
otherside = (len(a) - a.index(item)) - 1
temp = a[otherside]
a[otherside] = a[a.index(item)]
a[a.index(item)] = temp
return a
Powinno to zająć czas O (N).
Jeśli chcesz przechowywać elementy listy odwróconej w innej zmiennej, możesz użyć revArray = array[::-1]
lub revArray = list(reversed(array))
.
Ale pierwszy wariant jest nieco szybszy:
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))
Wynik:
Time: 0.00489711761475 s
Time: 0.00609302520752 s
timeit
.
W Pythonie także kolejnością list można manipulować sortowaniem , organizując zmienne w kolejności numerycznej / alfabetycznej:
print(sorted(my_list))
my_list.sort(), print(my_list)
Możesz sortować z flagą „reverse = True” :
print(sorted(my_list, reverse=True))
lub
my_list.sort(reverse=True), print(my_list)
Może nie chcesz sortować wartości, a jedynie odwracać wartości. Następnie możemy to zrobić w następujący sposób:
print(list(reversed(my_list)))
** Liczby mają pierwszeństwo przed alfabetem w kolejności wyświetlania. Organizacja wartości w języku Python jest niesamowita.
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]
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)
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
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.
def rev_slice(mylist):
a = mylist[::-1]
return a
reversed(obj)
funkcji iteratoraIstnieje reversed(indexed_object)
funkcja:
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
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) - 1
return [ 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 -10
return [ mylist[-index-1] for index in range(len(mylist)) ]
def rev_manual_index_loop(mylist):
a = []
reverse_index = len(mylist) - 1
for 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
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 < 15 else ''
# 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 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ów
index[0] and index[last]
def reverse(array):
n = array
first = 0
last = len(array) - 1
while first < last:
holder = n[first]
n[first] = n[last]
n[last] = holder
first += 1
last -= 1
return n
input -> [-1 ,1, 2, 3, 4, 5, 6]
output -> [6, 1, 2, 3, 4, 5, -1]
Możesz także użyć bitowego uzupełnienia indeksu tablicy, aby przechodzić przez tablicę w odwrotnej kolejności:
>>> array = [0, 10, 20, 40]
>>> [array[~i] for i, _ in enumerate(array)]
[40, 20, 10, 0]
Cokolwiek robisz, nie rób tego w ten sposób.
Innym rozwiązaniem byłoby użycie do tego numpy.flip
import numpy as np
array = [0, 10, 20, 40]
list(np.flip(array))
[40, 20, 10, 0]
Ś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]
.
array[:] = array[::-1]
def reverse(text):
output = []
for i in range(len(text)-1, -1, -1):
output.append(text[i])
return output
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 -= 1
print(inverse)
Najbardziej bezpośrednim tłumaczeniem twojego wymagania na Python jest ta for
instrukcja:
for i in xrange(len(array) - 1, -1, -1):
print i, array[i]
Jest to dość tajemnicze, ale może być przydatne.
def reverse(my_list):
L = len(my_list)
for i in range(L/2):
my_list[i], my_list[L-i - 1] = my_list[L-i-1], my_list[i]
return my_list
//
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.
>>> l = [1,2,3,4,5,6]; nl=[]
>>> while l:
nl.append(l.pop())
>>> print nl
[6, 5, 4, 3, 2, 1]
list_data = [1,2,3,4,5]
l = len(list_data)
i=l+1
rev_data = []
while l>0:
j=i-l
l-=1
rev_data.append(list_data[-j])
print "After Rev:- %s" %rev_data
posługiwać się
print(reversed(list_name))
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
Teraz powtarzaj w następujący sposób:
for x in reverse([1, 2, 3]):
print(x)
Jeśli potrzebujesz listy:
l = list(reverse([1, 2, 3]))
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ę.