我想知道如何通过值和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中的问题。因此,我需要以某种方式将名称变量“深度复制”到lambda
中。
P.S。是的,我知道打印后的生成器将耗尽。
您无法在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)