W Pythonie, jaki jest najlepszy sposób na utworzenie nowej listy, której elementy są takie same, jak elementy innej listy, ale w odwrotnej kolejności? (Nie chcę modyfikować istniejącej listy w miejscu).
Oto jedno rozwiązanie, które przyszło mi do głowy:
new_list = list(reversed(old_list))
Możliwe jest również skopiowanie, old_list
a następnie odwrócenie kopii w miejscu:
new_list = list(old_list) # or `new_list = old_list[:]`
new_list.reverse()
Czy jest lepsza opcja, którą przeoczyłem? Jeśli nie, czy istnieje ważny powód (taki jak efektywność), aby zastosować jedno z powyższych podejść zamiast drugiego?
źródło
list(reversed(oldlist))
. Poza drobną mikro-optymalizacją, czy jest jakiś powód, aby to[::-1]
zrobićreversed()
?reversed
ma ogromną zaletę, gdy lista nie jest potrzebna, ponieważ nie marnuje pamięci ani czasu na jej tworzenie. Ale kiedy zrobić potrzebujemy listy, używając[::-1]
zamiastlist(reversed())
jest analogiczna do stosując[listcomp]
zamiastlist(genexpr)
.[::-1]
oznacza to raczej usunięcie ostatniego elementu listy niż jego odwrócenie.reversed(list)
dokładnie określa, co robi; określa swój zamiar w sensie „Wyraźne jest lepsze niż ukryte”, „Czytelność się liczy” i „Rzadkie jest lepsze niż gęste”.A teraz
timeit
. Podpowiedź: Alex[::-1]
jest najszybszy :)$ 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
Aktualizacja: Dodano metodę kompilacji listy sugerowaną przez inspectorG4dget. Niech wyniki mówią same za siebie.
źródło
[::-1]
Korekty
Warto podać bazowy punkt odniesienia / korektę dla obliczeń czasu trwania przez sdolan, które pokazują wyniki „odwrócone” bez często niepotrzebnych
list()
konwersji. Talist()
operacja dodaje dodatkowe 26 usek do środowiska wykonawczego i jest potrzebna tylko w przypadku, gdy iterator jest niedopuszczalny.Wyniki:
reversed(lst) -- 11.2 usecs list(reversed(lst)) -- 37.1 usecs lst[::-1] -- 23.6 usecs
Obliczenia:
# 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
Wnioski:
Zakończenie tych testów
reversed()
jest szybsze niż wycinek[::-1]
o 12,4 usekźródło
''.join(reversed(['1','2','3']))
metoda wycinania jest nadal> 30% szybsza.