Rozumiem, że range()
funkcja, która w Pythonie 3 jest typem obiektu , generuje zawartość w locie, podobnie jak generator.
W takim przypadku oczekiwałbym, że następujący wiersz zajmie nadmiernie dużo czasu, ponieważ w celu ustalenia, czy 1 biliard mieści się w zakresie, należałoby wygenerować biliardy:
1000000000000000 in range(1000000000000001)
Co więcej: wydaje się, że bez względu na to, ile zer dodam, obliczenia mniej więcej zajmują tyle samo czasu (w zasadzie natychmiastowe).
Próbowałem też takich rzeczy, ale obliczenia są prawie natychmiastowe:
1000000000000000000000 in range(0,1000000000000000000001,10) # count by tens
Jeśli spróbuję zaimplementować własną funkcję zakresu, wynik nie będzie tak dobry !!
def my_crappy_range(N):
i = 0
while i < N:
yield i
i += 1
return
Co range()
robi obiekt pod maską, który sprawia, że jest tak szybki?
Odpowiedź Martijna Pietersa została wybrana ze względu na jej kompletność, ale zobacz także pierwszą odpowiedź abarnerta, aby uzyskać dobrą dyskusję na temat tego, co to znaczy range
być pełnoprawną sekwencją w Pythonie 3, oraz pewne informacje / ostrzeżenia dotyczące potencjalnej niespójności w zakresie __contains__
optymalizacji funkcji w różnych implementacjach Pythona . Inna odpowiedź abarnerta zawiera bardziej szczegółowe informacje i zawiera łącza dla osób zainteresowanych historią stojącą za optymalizacją w Pythonie 3 (i brakiem optymalizacji xrange
w Pythonie 2). Odpowiedzi poke i wim zawierają odpowiedni kod źródłowy C i wyjaśnienia dla zainteresowanych.
range
to generator?
xrange
taki sam jak Python3range
?
xrange()
obiekty nie mają __contains__
metody, więc sprawdzanie elementów musi przebiegać przez wszystkie elementy. Dodatkowo istnieje kilka innych zmian range()
, jak obsługuje krojenie (który ponownie zwraca range
obiekt) i teraz też ma count
i index
metody, aby był kompatybilny z collections.Sequence
ABC.
bool
lublong
typ, w przypadku innych typów obiektów zwariuje. Spróbuj z:100000000000000.0 in range(1000000000000001)