лямбда-захват по значению или ссылке - PullRequest
0 голосов
/ 20 октября 2019

Я хочу знать, как захватить переменную по значению и по ссылке в python.

Давайте посмотрим на код.

У меня есть MyClass с одним свойством - именем и спискомэкземпляры.

from itertools import ifilter

class MyClass:
  def __init__(self, name):
    self.name = name

mycl_list = [MyClass("boo"), MyClass("boo"),MyClass("bar"),MyClass("bar")]

Далее я хочу "отсортировать" эти экземпляры в словарь по их значениям. Проблема в том, что результирующий код возвращает «bar» вместо «boo».

Если я переключу ifilter на filter или list(ifilter(...)), тогда результирующий вывод будет «boo».

mycl_by_name = {}
for mycl_instance in mycl_list:
  name = mycl_instance.name
  mycl_by_name.setdefault(name, ifilter(lambda _mycl_instance: _mycl_instance.name == name, mycl_list))

for boo_named in mycl_by_name["boo"]:
  print (boo_named.name)

С точки зрения C ++ я вижу проблему захвата именной переменной в ifilter лямбду по ссылке. Так что мне нужно как-то «глубоко скопировать» переменную имени в lambda.

PS Да, я знаю, что генератор в словаре исчерпает себя после печати. ​​

1 Ответ

1 голос
/ 20 октября 2019
  • Вы не можете захватить по значению в python.

  • Вам необходимо ввести новую область видимости для решения проблемы. (да, в python цикл for не создает новую область видимости)


mycl_by_name = {}
for mycl_instance in mycl_list:
  def f():
    name = mycl_instance.name
    mycl_by_name.setdefault(name, ifilter(lambda _mycl_instance: _mycl_instance.name == name, mycl_list))
  f()

for boo_named in mycl_by_name["boo"]:
  print (boo_named.name)
...