Być może padłem ofiarą dezinformacji w sieci, ale wydaje mi się, że jest bardziej prawdopodobne, że coś źle zrozumiałem. Opierając się na tym, czego się do tej pory nauczyłem, range () jest generatorem, a generatory mogą być używane jako iteratory. Jednak ten kod:
myrange = range(10)
print(next(myrange))
daje mi ten błąd:
TypeError: 'range' object is not an iterator
Czego tu brakuje? Spodziewałem się, że to wypisze 0 i przejdzie do następnej wartości w myrange
. Jestem nowy w Pythonie, więc proszę przyjąć moje przeprosiny za dość podstawowe pytanie, ale nigdzie indziej nie mogłem znaleźć dobrego wyjaśnienia.
for
pętli.iter
których można użyć do uzyskania iteratora. Iteratory to obiekty, które można iterować przy użyciunext
. Generatory to kategoria iteratorów (funkcje generatora i wyrażenia generatora). Przynajmniej tak mi się wydaje ...Odpowiedzi:
range
jest klasą niezmiennych obiektów iterowalnych. Ich zachowanie w iteracji można porównać dolist
s: nie można ichnext
bezpośrednio wywoływać ; musisz uzyskać iterator za pomocąiter
.Więc nie,
range
nie jest generatorem.Możesz pomyśleć: „dlaczego nie uczyniły tego bezpośrednio iterowalnymi”? Cóż,
range
mają kilka przydatnych właściwości, które nie byłyby możliwe w ten sposób:start
,stop
istep
(od Pythona 3.3)count
orazindex
metody i obsługująin
,len
i__getitem__
operacje.range
wielokrotnie powtarzać to samo .>>> myrange = range(1, 21, 2) >>> myrange.start 1 >>> myrange.step 2 >>> myrange.index(17) 8 >>> myrange.index(18) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: 18 is not in range >>> it = iter(myrange) >>> it <range_iterator object at 0x7f504a9be960> >>> next(it) 1 >>> next(it) 3 >>> next(it) 5
źródło
range
obiektów jest to, że mają one__contains__
metodę, której można użyć do sprawdzenia, czy wartość mieści się w zakresie:5 in range(10) => True
range
jest leniwy (w porównaniu do Pythona 2, gdzie jest to po prostu funkcja zwracająca listę).range(0,10,3)[3]
i9 in range(0,10,3)
. Zakres to raczej leniwa lista.