Jak możesz utworzyć następującą listę range()w Pythonie?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Jak możesz utworzyć następującą listę range()w Pythonie?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Odpowiedzi:
użyj reversed()funkcji:
reversed(range(10))
To jest o wiele bardziej znaczące.
Aktualizacja:
Jeśli chcesz, aby była to lista (jak wskazał btk):
list(reversed(range(10)))
Aktualizacja:
Jeśli chcesz użyć tylko rangedo 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ć:
range(5, -1, -1)
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.
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))).
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ą?
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.
>>> range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> range(-2, 6, 2)
[-2, 0, 2, 4]
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).
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 liczby starti uzyskaj wyniki, o ile stopnie zostały osiągnięte, przesuwając się za stepkażdym razem.
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 ):
$ python -m timeit "[9-i for i in range(10)]"
1000000 loops, best of 3: 1.54 usec per loop
odpowiedź martineau (czytelna, jeśli znasz składnię rozszerzonych plasterków ):
$ python -m timeit "range(10)[::-1]"
1000000 loops, best of 3: 0.743 usec per loop
Odpowiedź Michała Šrajera (przyjęta, bardzo czytelna):
$ python -m timeit "reversed(range(10))"
1000000 loops, best of 3: 0.538 usec per loop
odpowiedź Benego (pierwsza, ale bardzo szkicowa w tym czasie ):
$ python -m timeit "range(9,-1,-1)"
1000000 loops, best of 3: 0.401 usec per loop
Ostatnia opcja jest łatwa do zapamiętania za pomocą range(n-1,-1,-1)notacji Val Neekmana .
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ć:
-1(to poprzednia wartość stop - 1, stopbyła równa 0).n-1.Odpowiednikiem zakresu (n) w odwrotnej kolejności byłoby:
n = 10
print range(n-1,-1,-1)
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(n))
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
Tylko jeśli ktoś się zastanawiał :)
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 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]
-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.
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[]__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 is not 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ść.
wierzę, że to może pomóc,
range(5)[::-1]
poniżej jest użycie:
for i in range(5)[::-1]:
print i
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(10))jest mniej podatna na błędy. Bez obrazy Asinox. Tylko uczciwa obserwacja.
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.
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ł.
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Jest poprawna forma. Jeśli użyjesz
reversed(range(10))
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.
TL; DR a[::-1] jest najszybszy.
Wymagania wstępne:
a = list(range(10))
%timeit [a[9-i] for i in range(10)]
1.27 µs ± 61.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit a[::-1]
135 ns ± 4.07 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit list(reversed(a))
374 ns ± 9.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%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