Najwyraźniej xrange jest szybszy, ale nie mam pojęcia, dlaczego jest szybszy (i nie ma żadnego dowodu poza anegdotą do tej pory, że jest szybszy) lub co poza tym jest inne
for i in range(0, 20):
for i in xrange(0, 20):
W Python 2.x:
range
tworzy listę, więc jeśli to zrobisz range(1, 10000000)
, tworzy listę w pamięci z 9999999
elementami.
xrange
jest obiektem sekwencji, który ocenia leniwie.
W Pythonie 3 range
robi odpowiednik Pythona xrange
i aby uzyskać listę, musisz użyć list(range(...))
.
xrange(x).__iter__()
jest generatorem.i
jest oceniany na żądanie, a nie podczas inicjalizacji.To prawda, ale w Pythonie 3
.range()
zostanie zaimplementowane przez Python 2.xrange()
. Jeśli musisz wygenerować listę, musisz:źródło
xrange
generatora? Jest to funkcja zawierającayield
instrukcję i zgodnie ze słownikiem funkcje takie nazywane są generatorami.Pamiętaj, użyj
timeit
modułu do przetestowania, który z małych fragmentów kodu jest szybszy!Osobiście zawsze używam
.range()
, chyba że mam do czynienia z naprawdę dużymi listami - jak widać pod względem czasowym, dla listy milionów wpisów, dodatkowy narzut wynosi tylko 0,04 sekundy. I, jak zauważa Corey, w Pythonie 3.0.xrange()
odejdzie i.range()
da ci ładne zachowanie iteratora.źródło
python -m timeit "for i in xrange(1000000):" " pass"
the extra overhead is only 0.04 seconds
nie jest to właściwy sposób patrzenia na to,(90.5-51.1)/51.1 = 1.771 times slower
jest poprawna, ponieważ przekazuje, że jeśli jest to główna pętla twojego programu, może to potencjalnie wąskie gardło. Jeśli jednak jest to niewielka część, 1,77x to niewiele.xrange
przechowuje tylko parametry zakresu i generuje liczby na żądanie. Jednak implementacja języka C w Pythonie obecnie ogranicza swoje argumenty do długości C:Zauważ, że w Pythonie 3.0 jest tylko
range
i zachowuje się jak 2.x,xrange
ale bez ograniczeń minimalnych i maksymalnych punktów końcowych.źródło
xrange zwraca iterator i zachowuje tylko jedną liczbę w pamięci na raz. zakres zachowuje całą listę liczb w pamięci.
źródło
xrange
nie nie zwraca iterator.and only keeps one number in memory at a time
a gdzie reszta jest umieszczona, proszę poprowadź mnie ..Spędź trochę czasu z Library Reference . Im bardziej go znasz, tym szybciej znajdziesz odpowiedzi na takie pytania. Szczególnie ważne jest kilka pierwszych rozdziałów na temat wbudowanych obiektów i typów.
Innym sposobem na znalezienie szybkiej informacji o konstrukcji Pythona jest docstring i funkcja pomocy:
źródło
Jestem zszokowany, nikt nie czytał dokumentu :
źródło
Daje to dwie zalety:
MemoryError
.źródło
Zaletę
xrange
ponad znajdzieszrange
w tym prostym przykładzie:Powyższy przykład nie odzwierciedla niczego znacznie lepszego w przypadku
xrange
.Teraz spójrz na następujący przypadek, w którym
range
jest naprawdę bardzo wolny, w porównaniu doxrange
.Za pomocą
range
tworzy już listę od 0 do 100000000 (czasochłonną), alexrange
jest generatorem i generuje liczby tylko na podstawie potrzeby, to znaczy, jeśli iteracja będzie kontynuowana.W Pythonie-3 implementacja
range
funkcjonalności jest taka sama jakxrange
w Pythonie-2, podczas gdy zlikwidowanoxrange
w Pythonie-3Happy Coding !!
źródło
To z powodów optymalizacji.
range () utworzy listę wartości od początku do końca (w twoim przykładzie 0 .. 20). To stanie się kosztowną operacją na bardzo dużych zasięgach.
Z drugiej strony xrange () jest znacznie bardziej zoptymalizowany. oblicza następną wartość tylko w razie potrzeby (za pomocą obiektu sekwencji Xrange) i nie tworzy listy wszystkich wartości, jak robi to zakres ().
źródło
range(x,y)
zwraca listę każdej liczby pomiędzy xiy, jeśli używaszfor
pętli, wtedyrange
jest wolniejsza. W rzeczywistościrange
ma większy zakres indeksu.range(x.y)
wypisze listę wszystkich liczb pomiędzy xiyxrange(x,y)
zwraca,xrange(x,y)
ale jeśli użyłeśfor
pętli, toxrange
jest szybszy.xrange
ma mniejszy zakres indeksu.xrange
nie tylko wydrukuje,xrange(x,y)
ale zachowa wszystkie zawarte w nim liczby.Jeśli użyjesz
for
pętli, to zadziałaNie ma dużej różnicy przy korzystaniu z pętli, choć jest różnica tylko podczas drukowania!
źródło
range (): range (1, 10) zwraca listę od 1 do 10 liczb i utrzymuje całą listę w pamięci.
xrange (): Podobnie jak range (), ale zamiast zwracać listę, zwraca obiekt, który na żądanie generuje liczby w zakresie. W przypadku zapętlania jest to nieco szybsze niż range () i bardziej wydajna pamięć. Obiekt xrange () jak iterator i generuje liczby na żądanie. (Lazy Evaluation)
źródło
Niektóre inne odpowiedzi wspominają, że Python 3 wyeliminował 2.x
range
i zmienił nazwę 2.xxrange
narange
. Jednakże, chyba że używasz wersji 3.0 lub 3.1 (którymi nikt nie powinien być), to w rzeczywistości jest to nieco inny typ.Jak mówią dokumenty 3.1 :
Jednak w wersji 3.2+
range
jest to pełna sekwencja - obsługuje rozszerzone wycinki i wszystkie metodycollections.abc.Sequence
z tą samą semantyką jaklist
. *I, przynajmniej w CPython i pypy (jedyne dwa 3.2 lub nowszym wdrożeń, które obecnie istnieją), ma też implementacje stałej porze
index
icount
metod orazin
operatora (tak długo, jak tylko go przekazywać liczby całkowite). Oznacza to, że pisanie123456 in r
jest rozsądne w wersji 3.2+, podczas gdy w wersji 2.7 lub 3.1 byłby to okropny pomysł.* Fakt, że
issubclass(xrange, collections.Sequence)
powracaTrue
w wersjach 2.6-2.7 i 3.0-3.1, jest błędem, który został naprawiony w wersji 3.2 i nie został przeniesiony.źródło
W python 2.x
zakres (x) zwraca listę utworzoną w pamięci za pomocą x elementów.
xrange (x) zwraca obiekt xrange, który jest generatorem obj, który generuje liczby na żądanie. są obliczane podczas pętli for (Lazy Evaluation).
W przypadku zapętlania jest to nieco szybsze niż zakres () i bardziej wydajna pamięć.
źródło
xrange()
nie jest generatorem.xrange(n)
.__ iter __ () `is.Podczas testowania zasięgu względem xrange w pętli (wiem, że powinienem użyć timeit , ale szybko zhackowałem go z pamięci za pomocą prostego przykładu ze zrozumieniem listy) znalazłem:
co daje:
Lub używając xrange w pętli for:
Czy testowanie mojego fragmentu jest prawidłowe? Jakieś komentarze na temat wolniejszej instancji Xrange? Lub lepszy przykład :-)
źródło
xrange
wydawałem się nieco szybszy, chociaż w Pythonie 3 porównanie jest teraz zbędne.timeit
jest. Zajmuje się bieganiem wiele razy, wyłączaniem GC, używaniem najlepszego zegara zamiasttime
itp.xrange () i range () w pythonie działają podobnie jak dla użytkownika, ale różnica pojawia się, gdy mówimy o tym, jak pamięć jest przydzielana przy użyciu obu funkcji.
Kiedy używamy range (), przydzielamy pamięć dla wszystkich generowanych zmiennych, więc nie zaleca się używania z większym nie. zmiennych do wygenerowania.
Z drugiej strony xrange () generuje tylko określoną wartość na raz i może być używana tylko z pętlą for do drukowania wszystkich wymaganych wartości.
źródło
zakres generuje całą listę i zwraca ją. xrange nie - generuje na żądanie liczby z listy.
źródło
xrange używa iteratora (generuje wartości w locie), zakres zwraca listę.
źródło
Co?
range
zwraca statyczną listę w czasie wykonywania.xrange
zwracaobject
(który działa jak generator, choć na pewno nie jest to jeden), z którego wartości są generowane w razie potrzeby.Kiedy stosować który?
xrange
jeśli chcesz wygenerować listę dla gigantycznego zasięgu, powiedzmy 1 miliard, zwłaszcza gdy masz „system wrażliwy na pamięć”, taki jak telefon komórkowy.range
jeśli chcesz kilkakrotnie iterować listę.PS: Python 3.x jest
range
funkcja == Python 2.x jestxrange
funkcja.źródło
xrange
nie zwraca obiektu generatora.Wszyscy to doskonale wyjaśnili. Ale chciałem to zobaczyć na własne oczy. Używam python3. Otworzyłem więc monitor zasobów (w systemie Windows!) I najpierw wykonałem następujące polecenie:
a następnie sprawdził zmianę w pamięci „W użyciu”. To było nieistotne. Następnie uruchomiłem następujący kod:
Natychmiast zajęło to sporo pamięci. I byłem przekonany. Możesz spróbować sam.
Jeśli używasz Python 2X, zamień „range ()” na „xrange ()” w pierwszym kodzie, a „list (range ())” na „range ()”.
źródło
Z dokumentacji pomocy.
Python 2.7.12
Python 3.5.2
Różnica jest widoczna. W Pythonie 2.x
range
zwraca listę,xrange
zwraca obiekt xrange, który jest iterowalny.W Python 3.x
range
staje sięxrange
Python 2.x ixrange
jest usuwany.źródło
W przypadku wymagań dotyczących skanowania / drukowania elementów 0-N zakres i zakres X działają w następujący sposób.
range () - tworzy nową listę w pamięci i przenosi całe 0 do N elementów (całkowicie N + 1) i drukuje je. xrange () - tworzy instancję iteratora, która skanuje elementy i przechowuje tylko bieżący napotkany element w pamięci, a zatem wykorzystuje tę samą ilość pamięci przez cały czas.
W przypadku, gdy wymagany element znajduje się nieco na początku listy, oszczędza to sporo czasu i pamięci.
źródło
xrange
nie tworzy instancji iteratora. Tworzyxrange
obiekt, który jest iterowalny, ale nie jest iteratorem - prawie (ale nie do końca) sekwencją, jak lista.Range zwraca listę, podczas gdy xrange zwraca obiekt xrange, który zajmuje tę samą pamięć niezależnie od wielkości zakresu, ponieważ w tym przypadku generowany jest tylko jeden element i dostępny na iterację, natomiast w przypadku użycia zakresu wszystkie elementy są generowane jednocześnie i są dostępne w pamięci.
źródło
Różnica maleje w przypadku mniejszych argumentów do
range(..)
/xrange(..)
:W tym przypadku
xrange(100)
jest tylko około 20% bardziej wydajny.źródło
zakres: -zakres zapełni wszystko naraz. co oznacza, że każda liczba zakresu zajmie pamięć.
xrange: -xrange jest czymś w rodzaju generatora, pojawi się na obrazie, gdy chcesz zakres liczb, ale nie chcesz, aby były przechowywane, na przykład gdy chcesz użyć pętli. tak wydajna pamięć.
źródło
Dodatkowo, jeśli do
list(xrange(...))
będzie równoważnerange(...)
.Więc
list
jest wolny.Również
xrange
naprawdę nie w pełni kończy sekwencjęDlatego to nie jest lista, to
xrange
obiektźródło
range()
w Pythonie2.x
Ta funkcja jest zasadniczo starą
range()
funkcją dostępną w Pythonie2.x
i zwraca instancjęlist
obiektu zawierającego elementy z określonego zakresu.Jednak ta implementacja jest zbyt nieefektywna, jeśli chodzi o inicjalizację listy z zakresem liczb. Na przykład
for i in range(1000000)
wykonanie polecenia byłoby bardzo kosztowne, zarówno pod względem zużycia pamięci, jak i czasu, ponieważ wymaga przechowywania tej listy w pamięci.range()
w Python3.x
ixrange()
Python2.x
Python
3.x
wprowadził nowszą implementacjęrange()
(podczas gdy nowsza implementacja była już dostępna w Pythonie2.x
za pośrednictwemxrange()
funkcję).range()
Wykorzystuje strategię zwaną oceny leniwy. Zamiast tworzyć ogromną listę elementów w zakresie, nowsza implementacja wprowadza klasęrange
, lekki obiekt, który reprezentuje wymagane elementy w danym zakresie, bez przechowywania ich wyraźnie w pamięci (może to brzmieć jak generatory, ale koncepcja leniwej oceny jest różne).Jako przykład weź pod uwagę następujące kwestie:
i
źródło
Zobacz ten post aby znaleźć różnicę między zasięgiem a zasięgiem xrange:
Cytować:
źródło
xrange
nie jest iteratorem. Lista zwracana przezrange
nie obsługuje iteracji (lista jest w zasadzie prototypowym przykładem iterowalności). Ogólna korzyśćxrange
nie jest „minimalna”. I tak dalej.