首页 > 解决方案 > lambda capture by value or reference

问题描述

I want to know how to capture variable by value and by reference in python.

Lets look at the code.

I have MyClass with one property - name and list of instances.

from itertools import ifilter

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

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

Next I want to "sort" these instances into dictionary by their values. The problem is that resulting code returns "bar" instead of "boo".

If I switch ifilter to filter or list(ifilter(...)) then resulting output will be "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)

From C++ perspective I see the problem in capturing name variable into ifilter lambda by reference. So I need to "deepcopy" name variable into lambda somehow.

P.S. Yes I know that generator in dictionaty will become exhausted after printing.

标签: pythonlambdapython-2.x

解决方案


  • 您不能在 python 中按值捕获。

  • 您需要引入新的范围来解决问题。(是的,在pythonfor-loop 中不会创建新范围)


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)

推荐阅读