Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 14, 2022 12:39:28

Rikin
Зарегистрирован: 2020-11-14
Сообщения: 56
Репутация: +  0  -
Профиль   Отправить e-mail  

Выбрать нескольких гостей из списка. Задействуя наследование

FishHook
xam1816зачем вы постоянно используете map и filter? Это уже давно устаревшие и нерекомендуемые функции, они отнюдь не добавляют вашему коду ни читабельности ни перформанса. Зачем вы кастуете генератор к списку и тут же его итерируете?

У нас пока то что мы из примеров перенимаем и приспосабливаем к себе.
А что оно и “без” бывает - это еще не всегда известно заранее, а познаётся - вот от вас.

Вопрос решён, спасибо.

Офлайн

#2 Янв. 14, 2022 12:42:18

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8006
Репутация: +  558  -
Профиль   Отправить e-mail  

Выбрать нескольких гостей из списка. Задействуя наследование

Rikin
У нас пока то что мы из примеров перенимаем и приспосабливаем к себе.
из примеров, конечно, хорошо, но учиться лучше не на примерах, а по учебникам



Офлайн

#3 Янв. 15, 2022 01:54:54

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 8147
Репутация: +  734  -
Профиль   Отправить e-mail  

Выбрать нескольких гостей из списка. Задействуя наследование

FishHook
зачем вы постоянно используете map и filter? Это уже давно устаревшие и нерекомендуемые функции
Кем не рекомендуемые? Устаревшие функции - это map и filter во втором питоне, так как во втором питоне они генерируют списки, что тратит память и время. В третьем питоне они, как и функции из модуля itertools, возвращают итераторы.

И никто не обязывает тебя использовать их с лямбда-функциями! Можно один раз создать функцию и использовать её, уже созданную со всеми затратами, многократно потом во всех подобных вызовах.

  
>>> volunteer_datas = [
...     {'name': 'Ivanov', 'place': 'Moscow', 'status': 'Consultant'},
...     {'name': 'Pertov', 'place': 'St. Petersburg', 'status': 'Mentor'},
...     {'name': 'Schwarz', 'place': 'Viena', 'status': 'Trainer'}]
>>> 
>>> def q(x):
...     return x['name'] in ('Pertov', 'Schwarz')
... 
>>> filtered = filter(q, volunteer_datas)
>>> 
>>> filtered
<filter object at 0x7fd9e0943828>
>>> 
>>> print(*filtered, sep='\n')
{'name': 'Pertov', 'place': 'St. Petersburg', 'status': 'Mentor'}
{'name': 'Schwarz', 'place': 'Viena', 'status': 'Trainer'}
>>>

FishHook
Зачем вы кастуете генератор к списку
Там нет генератора. Знаешь, как отличить генератор от итерабельного? По наличию методов send() и throw(). Если их нет, то это не генератор.
  
>>> filtered.send
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'filter' object has no attribute 'send'
>>> filtered.throw
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'filter' object has no attribute 'throw'
>>>

А наличие методов __iter__() и __next__() говорит о соблюдении протокола итератора и возможности применения встроенных функций iter() и next() к объекту.
  
>>> filtered.__iter__
<method-wrapper '__iter__' of filter object at 0x7fd9e0943828>
>>> filtered.__next__
<method-wrapper '__next__' of filter object at 0x7fd9e0943828>
>>>
Поэтому это итератор. Он протокол итератора соблюдает.



Отредактировано py.user.next (Янв. 15, 2022 02:06:21)

Офлайн

#4 Янв. 15, 2022 11:30:17

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8006
Репутация: +  558  -
Профиль   Отправить e-mail  

Выбрать нескольких гостей из списка. Задействуя наследование

py.user.next
Кем не рекомендуемые?
Например мной. Да много кем, Марком Лутцем, в частности

py.user.next
Там нет генератора.
Да идёте вы, дорогой друг, нахер
 print(type((x for x in range(10))))
>>> <class 'generator'>



Офлайн

#5 Янв. 15, 2022 18:39:56

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 8147
Репутация: +  734  -
Профиль   Отправить e-mail  

Выбрать нескольких гостей из списка. Задействуя наследование

Вот ты пишешь 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
  
(x for x in range(10))
  
>>> 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__'
>>>



Отредактировано py.user.next (Янв. 15, 2022 19:03:06)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version