Возможно, я стал жертвой дезинформации в сети, но я думаю, что более вероятно, что я просто что-то неправильно понял. На основании того, что я узнал до сих пор, range () является генератором, а генераторы могут использоваться как итераторы. Однако этот код:
myrange = range(10)
print(next(myrange))
дает мне эту ошибку:
TypeError: 'range' object is not an iterator
Что мне здесь не хватает? Я ожидал, что это напечатает 0 и перейдет к следующему значению в myrange
. Я новичок в Python, поэтому примите мои извинения за довольно простой вопрос, но я нигде не нашел хорошего объяснения.
for
цикле.iter
можно использовать для получения итератора. Итераторы - это объекты, которые можно повторять с помощьюnext
. Генераторы - это категория итераторов (функций генератора и выражений генератора). По крайней мере, я так думаю ...Ответы:
range
это класс неизменяемых итеративных объектов. Их итерационное поведение можно сравнить сlist
s: вы не можете обращаться к нимnext
напрямую; вам нужно получить итератор, используяiter
.Так что нет,
range
это не генератор.Вы можете подумать: «Почему они не сделали это напрямую итеративным»? Что ж, у
range
s есть несколько полезных свойств, которые были бы невозможны таким образом:start
,stop
иstep
(начиная с Python 3.3),count
иindex
методы, которые они поддерживаютin
,len
и__getitem__
операции.range
несколько раз.>>> 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
источник
range
объектов заключается в том, что у них есть__contains__
метод, который можно использовать для проверки, находится ли значение в диапазоне:5 in range(10) => True
range
является ленивым ( по сравнению с Python 2 , где это просто функция , которая возвращает список).range(0,10,3)[3]
и9 in range(0,10,3)
. Range - это довольно ленивый список.