Вот ты пишешь
xam1816'у, что у него там генератор
xam1816
volunteer_datas = [
{"name": "Ivanov", "place": "Moscow", "status": 'Consultant'},
{"name": "Pertov", "place": "St. Petersburg", "status": 'Mentor'},
{"name": "Schwarz", "place": "Viena", "status": 'Trainer'}]
for i in list(filter(lambda d: d['name'] in ("Pertov", "Schwarz"), volunteer_datas)):
print(i)
FishHook
xam1816
зачем вы постоянно используете map и filter? Это уже давно устаревшие и нерекомендуемые функции, они отнюдь не добавляют вашему коду ни читабельности ни перформанса. Зачем вы кастуете генератор к списку и тут же его итерируете?
А у него там генератора нет. Это значит, что ты не понимаешь, где генератор, а где не генератор, потому что
не читал официальную доку с
python.org по генераторам и не знаешь, что генератор очень точно определяется в любой ситуации как раз по наличию этих методов, которые есть только у генератора. Так вот прочитай её сначала, чтобы просто про генераторы всё узнать. Ты же про эти методы не знаешь, правда? А для чего эти методы в генераторе нужны, ты не думал? То есть ты и про сопрограммы не в курсе, получается.
FishHook
Марком Лутцем, в частности
Где он утверждает это не в контексте второго питона? Он может максимум сказать, что
во втором питоне не используйте их, а используйте xrange(), itertools.imap(), itertools.ifilter() и прочее, чтобы не создавать списки каждый раз. Это максимум.
FishHook
>>> g = (x for x in range(10))
>>> g.send
<built-in method send of generator object at 0x7f0bf3095620>
>>> g.throw
<built-in method throw of generator object at 0x7f0bf3095620>
>>> g.close
<built-in method close of generator object at 0x7f0bf3095620>
>>>
А вот range-объект - это не генератор
>>> r = range(10)
>>> r.send
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'range' object has no attribute 'send'
>>> r.throw
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'range' object has no attribute 'throw'
>>> r.close
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'range' object has no attribute 'close'
>>>
Любой генератор можно закрыть в любое время
>>> g = (x for x in range(10))
>>> next(g)
0
>>> next(g)
1
>>> g.close()
>>>
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
Но ни filter-объект, ни map-объект, ни range-объект ты не закроешь
>>> f = filter(None, 'abc')
>>> f.close
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'filter' object has no attribute 'close'
>>>
>>> m = map(None, 'abc')
>>> m.close
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'map' object has no attribute 'close'
>>>
У них нет этого генераторного метода.
А к range-объекту ты даже next() не применишь, потому что это не только не генератор, но это даже не итератор
>>> r = range(10)
>>> next(r)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'range' object is not an iterator
>>>
Он не соблюдает протокол итератора, по которому каждый итератор имеет метод __next__(), поэтому итератором не является. Он является только итераблом (объектом, для которого можно получить итератор, так как у объекта есть метод __iter__() ). Для него можно вызвать только iter(), чтобы получить итератор, у которого уже будет __next__() и к которому можно глобальную функцию next() применять.
>>> r = range(10)
>>> next(r)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'range' object is not an iterator
>>>
>>> i = iter(r)
>>> next(i)
0
>>> next(i)
1
>>> i.close()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'range_iterator' object has no attribute 'close'
>>>
И если ты range() используешь в цикле for, то цикл for именно таким макаром и перебирает этот range-объект; он сначала вызывает для него iter(), чтобы получить итератор. А вызов iter() возможен только потому, что у range-объекта есть метод __iter__().
>>> r = range(10)
>>>
>>> r.__iter__
<method-wrapper '__iter__' of range object at 0x7f8a6419fba0>
>>>
>>> r.__next__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'range' object has no attribute '__next__'
>>>