【问题标题】:Dictionary With Lambda Values Updates All Entries具有 Lambda 值的字典更新所有条目
【发布时间】:2018-09-29 15:01:04
【问题描述】:

我在 Python 2.7 中。我有两个类和一个命名元组。一个类包含一个字典作为实例属性和一个分配给该字典的函数。 (这是情况的一个非常简化的版本)。 namedtuple 很简单。另一个类是通过add_to_test_dict 函数调用向test_dict 添加条目。

然后我实例化 DictManipulator 并调用test 函数:

from collections import namedtuple


class DictHolder(object):
    def __init__(self):
        self.test_dict = {}
    def add_to_test_dict(self, key, val):
        self.test_dict[key] = val

TestTuple = namedtuple('TestTuple', 'name data')

class DictManipulator(object):
    def test(self):
        named_tuple_list = [TestTuple(name='key1', data=1), TestTuple(name='key2', data=1000)]
        self.my_dh = DictHolder()
        for item in named_tuple_list:
            self.my_dh.add_to_test_dict(item.name, lambda: item.data)

my_dm = DictManipulator()
my_dm.test()
print('key1 value: ', my_dm.my_dh.test_dict['key1']())
print('key2 value: ', my_dm.my_dh.test_dict['key2']())
# ('key1 value: ', 1000)
# ('key2 value: ', 1000)

为什么两个键都返回相同的值?我已经进行了足够多的实验,可以说原始的 named_tuple_list 没有更新,并且我尝试使用lambda: copy.deepcopy(item.data),但这也不起作用。非常感谢各位。

【问题讨论】:

  • 典型的后期绑定问题。在你的循环中尝试lambda x=item: x.data
  • 你这个美人!感谢您的帮助。它现在按我的预期工作。

标签: python python-2.7 lambda namedtuple


【解决方案1】:

这是一个典型的后期绑定问题(见common gotchas):当函数(与它无关的lambda/匿名)被调用时,它们访问item的当前值,这是最后一个从循环。试试

lambda x=item: x.data 

改为在您的循环中。这是可行的,因为默认参数在定义时绑定到函数,而公共局部变量在调用时进行评估。

类似(可能重复)问题:Python Lambda in a loop

【讨论】:

  • 感谢您的澄清。这对我来说是个盲点。
  • @semi.suite 是的,这是 Python 中的一个常见问题 :) 我链接了该主题的搭便车者部分。
猜你喜欢
  • 2011-07-15
  • 1970-01-01
  • 2018-12-04
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多