Chociaż „jest” mniej wydajny. I nie można na nim wykonywać operacji krojenia.
Jakob Bowyer,
6
Ta odpowiedź jest bardzo jasna i łatwa do zrozumienia, ale musi być range(10), nie range(9). Ponadto, jeśli chcesz mieć w pełni uformowaną listę (do krojenia itp.), Powinieneś to zrobić list(reversed(range(10))).
John Y
5
W ten sposób powstaje iterator, OP poprosił o wynik w postaci listy.
btk
6
Używanie „odwróconego” z generatorem Pythona (zakładając, że mówimy o wbudowanym zakresie Pythona 3) jest po prostu błędne koncepcyjnie i uczy złych nawyków nieuwzględniania złożoności pamięci / przetwarzania podczas programowania w języku wysokiego poziomu.
thedk
7
W Python3 ogólnie reversednie akceptuje generatorów, ale akceptuje range. Dlaczego reversed(range(10000))trzeba przydzielić pamięć dla całej listy? rangemoże zwrócić obiekt, który implementuje __reversed__metodę, która umożliwia wydajną iterację wsteczną?
avmohan,
312
Skorzystaj z wbudowanej funkcji „range”. Podpis jest range(start, stop, step). W ten sposób powstaje sekwencja, która daje liczby, zaczynając od starti kończąc, jeśli stopzostała osiągnięta, z wyłączeniem stop.
W Pythonie 3 tworzy to obiekt nie będący listą range, który działa skutecznie jak lista tylko do odczytu (ale zużywa znacznie mniej pamięci, szczególnie w przypadku dużych zakresów).
Czy możesz to również wyjaśnić, czy możesz mi polecić dowolną stronę internetową / książkę pdf dla python
ramesh.mimit
8
@ramesh Jeśli uruchomisz help(range)w powłoce pytona, poda ci argumenty. Są to liczba na początek, liczba na końcu (wyłącznie) i krok do podjęcia, więc zaczyna się od 9 i odejmuje 1, aż dojdzie do -1 (w tym momencie zatrzymuje się bez powrotu, dlatego zakres kończy się o 0)
Michael Mrozek
3
@ ramesh.mimit: Przejdź na oficjalną stronę Pythona. Jest tam pełna dokumentacja, w tym świetny samouczek.
John Y,
5
Naprawdę jest to właściwa odpowiedź, ale można ją dokładniej wyjaśnić. range(start, stop, step) - zacznij od liczby starti uzyskaj wyniki, o ile stopnie zostały osiągnięte, przesuwając się za stepkażdym razem.
Pan B
43
Możesz użyć range(10)[::-1]tej samej rzeczy range(9, -1, -1)i prawdopodobnie bardziej czytelnej (jeśli znasz zwykły sequence[::-1]idiom Pythona).
Dla tych, którzy są zainteresowani „wydajnością” dotychczas zebranych opcji ...
Odpowiedź Jaime'a RGP skłoniła mnie do ponownego uruchomienia komputera po zorientowaniu się w czasie nieco „trudnego” rozwiązania Jasona dosłownie po mojej własnej sugestii (poprzez komentarz). Aby zaoszczędzić ciekawskim przestojów, przedstawiam tutaj moje wyniki (najgorsze pierwsze):
Nie ma sensu używać, reverseponieważ metoda zakresu może zwrócić listę odwróconą.
Gdy masz iterację n elementów i chcesz zastąpić zwróconą przez range(start, stop, step)ciebie kolejność listy , musisz użyć trzeciego parametru zakresu, który identyfikuje stepi ustawia go -1, pozostałe parametry należy odpowiednio dostosować:
Zapewnić zatrzymanie parametr jak -1(to poprzednia wartość stop - 1, stopbyła równa 0).
Jako parametr początkowy użyj n-1.
Odpowiednikiem zakresu (n) w odwrotnej kolejności byłoby:
Szczerze mówiąc, uważam to za mniej intuicyjne niżreversed(range(n))
Nicholas Hamilton
1
@NicholasHamilton Zgadzam się z tobą, jednak pomysł na tę odpowiedź polega na zużyciu mniejszych zasobów ... (a pytanie dotyczyło użycia tylko funkcji zakresu :))
Andriy Ivaneyko
Ok, nie martw się, myślę, że to zależy od sytuacji. Na przykład, jeśli funkcja zakresu jest używana jako indeks dla pętli, będzie to miało ograniczony efekt, jednak jeśli zostanie użyta w pętli zewnętrznej, wówczas koszt się zwiększy ...
Nicholas Hamilton,
8
Poza tym czytelność reversed(range(n))wydaje się szybsza niż range(n)[::-1].
$ python -m timeit "reversed(range(1000000000))"1000000 loops, best of 3:0.598 usec per loop
$ python -m timeit "range(1000000000)[::-1]"1000000 loops, best of 3:0.945 usec per loop
dobrze mieć jakieś numery :) - dlaczego też nie dodałeś range(1000000000-1,-1,-1)?
Wolf
... lepiej nie próbuj timeit range(1000000000-1,-1,-1)w wierszu poleceń, zamiast tego zobacz moje wyniki :-)
Wolf
6
Wymaganie zawarte w tym pytaniu wymaga listliczby całkowitej 10 w porządku malejącym. Stwórzmy więc listę w Pythonie.
# This meets the requirement.# But it is a bit harder to wrap one's head around this. right?>>> range(10-1,-1,-1)[9,8,7,6,5,4,3,2,1,0]# let's find something that is a bit more self-explanatory. Sounds good?# ----------------------------------------------------# This returns a list in ascending order.# Opposite of what the requirement called for.>>> range(10)[0,1,2,3,4,5,6,7,8,9]# This returns an iterator in descending order.# Doesn't meet the requirement as it is not a list.>>> reversed(range(10))<listreverseiterator object at 0x10e14e090># This returns a list in descending order and meets the requirement>>> list(reversed(range(10)))[9,8,7,6,5,4,3,2,1,0]
Bardzo podoba mi się potrójny-1 To właśnie ten wzór ułatwia utrzymanie wrap one's head around this- Dzisiaj dowiedziałem się, że jeśli naprawdę musi być wydajny , używaj go, range(n-1, -1, -1)gdy przemierzasz zasięg w odwrotnej kolejności.
Wolf
5
Możesz drukować liczby odwrotne za pomocą Range () BIF Like,
for number in range (10,0,-1):print( number )
Wynik wyniesie [10,9,8,7,6,5,4,3,2,1]
range () - zakres (początek, koniec, przyrost / spadek), gdzie początek obejmuje, koniec jest wyłączny, a przyrost może być dowolnymi liczbami i zachowuje się jak krok
Często zadawane pytanie brzmi, czy range(9, -1, -1)lepiej niż reversed(range(10))w Pythonie 3? Ludzie, którzy pracowali w iteratorach w innych językach, od razu myślą, że reverse () musi buforować wszystkie wartości, a następnie wracać w odwrotnej kolejności. Chodzi o to, że reversed()operator Pythona nie działa, jeśli obiekt jest tylko iteratorem. Obiekt musi mieć jeden z dwóch poniżej dwóch, aby funkcja reverse () działała:
len()Indeksy wsparcia i całkowite za pośrednictwem[]
Lub __reversed__()zaimplementuj metodę.
Jeśli spróbujesz użyć odwróconej () na obiekcie, który nie ma żadnego z powyższych, otrzymasz:
>>>[reversed((x for x in range(10)))]TypeError:'generator' object isnot reversible
Krótko mówiąc, Python reversed()jest przeznaczony tylko do obiektów podobnych do tablicy, więc powinien mieć taką samą wydajność jak iteracja do przodu.
Ale co z range()? Czy to nie generator? W Pythonie 3 jest to generator, ale zawinięty w klasę, która implementuje oba powyższe. Więc range(100000)nie zajmuje dużo pamięci, ale nadal obsługuje wydajne indeksowanie i cofanie.
Podsumowując, możesz używać reversed(range(10))bez żadnego wpływu na wydajność.
Twoja odpowiedź pokazuje, dlaczego reversed(range(10))jest mniej podatna na błędy. Bez obrazy Asinox. Tylko uczciwa obserwacja.
Michał Šrajer
Nie wiem, czy standardem jest pozostawienie błędnych odpowiedzi na wyświetlaczu. Czy ja lub ktoś mogę to poprawić, a nawet usunąć?
sinekonata
3
@sine, nie, po prostu zostaw to i zastanawiaj się, jak to nagromadziło 3 głosy poparcia ... Przypuszczam, że mógłbyś oflagować go dla uwagi moderatora (duplikat odpowiedzi z 18 miesięcy wcześniej, z wyjątkiem zepsutych), nie jestem pewien, czy go usuną.
Nie musisz koniecznie używać funkcji zakresu, możesz po prostu zrobić listę [:: - 1], która powinna szybko zwrócić listę w odwrotnej kolejności, bez żadnych dodatków.
To wydaje się być rozwiązaniem sugerowanym w poprzedniej odpowiedzi . Wygląda też na to, że próbujesz skomentować inną poprzednią odpowiedź - zanim będziesz mógł to zrobić, musisz uzyskać trochę więcej reputacji.
Grisha Levit
1
Załóżmy, że masz listę o nazwie a = {1,2,3,4,5} Teraz, jeśli chcesz wydrukować listę w odwrotnej kolejności, po prostu użyj następującego kodu.
a.reverse
for i in a:print(i)
Wiem, że zapytałeś za pomocą zasięgu, ale już na nie odpowiedział.
nie dostaniesz 0 przypadku. Powiedzmy na przykład, że twoja 10 nie jest liczbą magiczną, a zmienna, której używasz do wyszukiwania, zaczyna się od tyłu. Jeśli twoja n wynosi 0, odwrócony (zakres (0)) nie zostanie wykonany, co jest błędne, jeśli przypadkiem masz pojedynczy obiekt w indeksie zerowym.
Pomyślałem, że wielu (jak ja) może być bardziej zainteresowanych zwykłym przypadkiem przeszukiwania istniejącej listy w odwrotnej kolejności , jak to podano w tytule, zamiast generowania indeksów dla takiego przejścia.
Pomimo tego, że wszystkie prawidłowe odpowiedzi są w tym przypadku idealnie w porządku, chcę zauważyć, że porównanie wydajności wykonane w odpowiedzi Wolfa służy wyłącznie do generowania indeksów. Podjąłem więc podobny test porównawczy dla istniejącej listy w odwrotnej kolejności.
%timeit [a[i]for i in range(9,-1,-1)]1.09µs ±11.1 ns per loop (mean ± std. dev. of 7 runs,1000000 loops each)
Jak widać, w tym przypadku nie ma potrzeby jawnego generowania indeksów, więc najszybszą metodą jest ta, która wykonuje mniej dodatkowych działań.
NB: Testowałem w JupyterLab, który ma przydatne „magiczne polecenie” %timeit. Używa standardu timeit.timeitpod maską. Przetestowano pod kątem Python 3.7.3
Odpowiedzi:
użyj
reversed()
funkcji:To jest o wiele bardziej znaczące.
Aktualizacja:
Jeśli chcesz, aby była to lista (jak wskazał btk):
Aktualizacja:
Jeśli chcesz użyć tylko
range
do osiągnięcia tego samego rezultatu, możesz użyć wszystkich jego parametrów.range(start, stop, step)
Na przykład, aby wygenerować listę
[5,4,3,2,1,0]
, możesz użyć:Może to być mniej intuicyjne, ale jak wspomniano w komentarzach, jest to bardziej wydajne i właściwe użycie zakresu dla odwróconej listy.
źródło
range(10)
, nierange(9)
. Ponadto, jeśli chcesz mieć w pełni uformowaną listę (do krojenia itp.), Powinieneś to zrobićlist(reversed(range(10)))
.reversed
nie akceptuje generatorów, ale akceptujerange
. Dlaczegoreversed(range(10000))
trzeba przydzielić pamięć dla całej listy?range
może zwrócić obiekt, który implementuje__reversed__
metodę, która umożliwia wydajną iterację wsteczną?Skorzystaj z wbudowanej funkcji „range”. Podpis jest
range(start, stop, step)
. W ten sposób powstaje sekwencja, która daje liczby, zaczynając odstart
i kończąc, jeślistop
została osiągnięta, z wyłączeniemstop
.W Pythonie 3 tworzy to obiekt nie będący listą
range
, który działa skutecznie jak lista tylko do odczytu (ale zużywa znacznie mniej pamięci, szczególnie w przypadku dużych zakresów).źródło
help(range)
w powłoce pytona, poda ci argumenty. Są to liczba na początek, liczba na końcu (wyłącznie) i krok do podjęcia, więc zaczyna się od 9 i odejmuje 1, aż dojdzie do -1 (w tym momencie zatrzymuje się bez powrotu, dlatego zakres kończy się o 0)range(start, stop, step)
- zacznij od liczbystart
i uzyskaj wyniki, o ilestop
nie zostały osiągnięte, przesuwając się zastep
każdym razem.Możesz użyć
range(10)[::-1]
tej samej rzeczyrange(9, -1, -1)
i prawdopodobnie bardziej czytelnej (jeśli znasz zwykłysequence[::-1]
idiom Pythona).źródło
Dla tych, którzy są zainteresowani „wydajnością” dotychczas zebranych opcji ...
Odpowiedź Jaime'a RGP skłoniła mnie do ponownego uruchomienia komputera po zorientowaniu się w czasie nieco „trudnego” rozwiązania Jasona dosłownie po mojej własnej sugestii (poprzez komentarz). Aby zaoszczędzić ciekawskim przestojów, przedstawiam tutaj moje wyniki (najgorsze pierwsze):
Odpowiedź Jasona (może po prostu wycieczka w moc rozumienia listy ):
odpowiedź martineau (czytelna, jeśli znasz składnię rozszerzonych plasterków ):
Odpowiedź Michała Šrajera (przyjęta, bardzo czytelna):
odpowiedź Benego (pierwsza, ale bardzo szkicowa w tym czasie ):
Ostatnia opcja jest łatwa do zapamiętania za pomocą
range(n-1,-1,-1)
notacji Val Neekmana .źródło
rozwiąże ten problem. Wyjdzie 8 do 1, a -1 oznacza odwróconą listę
źródło
Nie ma sensu używać,
reverse
ponieważ metoda zakresu może zwrócić listę odwróconą.Gdy masz iterację n elementów i chcesz zastąpić zwróconą przez
range(start, stop, step)
ciebie kolejność listy , musisz użyć trzeciego parametru zakresu, który identyfikujestep
i ustawia go-1
, pozostałe parametry należy odpowiednio dostosować:-1
(to poprzednia wartośćstop - 1
,stop
była równa0
).n-1
.Odpowiednikiem zakresu (n) w odwrotnej kolejności byłoby:
źródło
reversed(range(n))
Poza tym czytelność
reversed(range(n))
wydaje się szybsza niżrange(n)[::-1]
.Tylko jeśli ktoś się zastanawiał :)
źródło
range(1000000000-1,-1,-1)
?timeit range(1000000000-1,-1,-1)
w wierszu poleceń, zamiast tego zobacz moje wyniki :-)Wymaganie zawarte w tym pytaniu wymaga
list
liczby całkowitej 10 w porządku malejącym. Stwórzmy więc listę w Pythonie.źródło
-1
To właśnie ten wzór ułatwia utrzymaniewrap one's head around this
- Dzisiaj dowiedziałem się, że jeśli naprawdę musi być wydajny , używaj go,range(n-1, -1, -1)
gdy przemierzasz zasięg w odwrotnej kolejności.Możesz drukować liczby odwrotne za pomocą Range () BIF Like,
Wynik wyniesie [10,9,8,7,6,5,4,3,2,1]
range () - zakres (początek, koniec, przyrost / spadek), gdzie początek obejmuje, koniec jest wyłączny, a przyrost może być dowolnymi liczbami i zachowuje się jak krok
źródło
Często zadawane pytanie brzmi, czy
range(9, -1, -1)
lepiej niżreversed(range(10))
w Pythonie 3? Ludzie, którzy pracowali w iteratorach w innych językach, od razu myślą, że reverse () musi buforować wszystkie wartości, a następnie wracać w odwrotnej kolejności. Chodzi o to, żereversed()
operator Pythona nie działa, jeśli obiekt jest tylko iteratorem. Obiekt musi mieć jeden z dwóch poniżej dwóch, aby funkcja reverse () działała:len()
Indeksy wsparcia i całkowite za pośrednictwem[]
__reversed__()
zaimplementuj metodę.Jeśli spróbujesz użyć odwróconej () na obiekcie, który nie ma żadnego z powyższych, otrzymasz:
Krótko mówiąc, Python
reversed()
jest przeznaczony tylko do obiektów podobnych do tablicy, więc powinien mieć taką samą wydajność jak iteracja do przodu.Ale co z
range()
? Czy to nie generator? W Pythonie 3 jest to generator, ale zawinięty w klasę, która implementuje oba powyższe. Więcrange(100000)
nie zajmuje dużo pamięci, ale nadal obsługuje wydajne indeksowanie i cofanie.Podsumowując, możesz używać
reversed(range(10))
bez żadnego wpływu na wydajność.źródło
wierzę, że to może pomóc,
poniżej jest użycie:
źródło
źródło
reversed(range(10))
jest mniej podatna na błędy. Bez obrazy Asinox. Tylko uczciwa obserwacja.Używanie bez [:: - 1] lub odwróconego -
źródło
"python!"[::-1]
?źródło
Nie musisz koniecznie używać funkcji zakresu, możesz po prostu zrobić listę [:: - 1], która powinna szybko zwrócić listę w odwrotnej kolejności, bez żadnych dodatków.
źródło
Załóżmy, że masz listę o nazwie a = {1,2,3,4,5} Teraz, jeśli chcesz wydrukować listę w odwrotnej kolejności, po prostu użyj następującego kodu.
Wiem, że zapytałeś za pomocą zasięgu, ale już na nie odpowiedział.
źródło
Jest poprawna forma. Jeśli użyjesz
nie dostaniesz 0 przypadku. Powiedzmy na przykład, że twoja 10 nie jest liczbą magiczną, a zmienna, której używasz do wyszukiwania, zaczyna się od tyłu. Jeśli twoja n wynosi 0, odwrócony (zakres (0)) nie zostanie wykonany, co jest błędne, jeśli przypadkiem masz pojedynczy obiekt w indeksie zerowym.
źródło
Pomyślałem, że wielu (jak ja) może być bardziej zainteresowanych zwykłym przypadkiem przeszukiwania istniejącej listy w odwrotnej kolejności , jak to podano w tytule, zamiast generowania indeksów dla takiego przejścia.
Pomimo tego, że wszystkie prawidłowe odpowiedzi są w tym przypadku idealnie w porządku, chcę zauważyć, że porównanie wydajności wykonane w odpowiedzi Wolfa służy wyłącznie do generowania indeksów. Podjąłem więc podobny test porównawczy dla istniejącej listy w odwrotnej kolejności.
TL; DR
a[::-1]
jest najszybszy.Wymagania wstępne:
Odpowiedź Jasona :
odpowiedź martineau :
Odpowiedź Michała Šrajera :
odpowiedź Bene'a :
Jak widać, w tym przypadku nie ma potrzeby jawnego generowania indeksów, więc najszybszą metodą jest ta, która wykonuje mniej dodatkowych działań.
NB: Testowałem w JupyterLab, który ma przydatne „magiczne polecenie”
%timeit
. Używa standardutimeit.timeit
pod maską. Przetestowano pod kątem Python 3.7.3źródło