我试图通过使用字典来包含和索引与某些计算相关的函数来简化我的一些代码。我遇到了一个问题,字典中的函数变得困惑并且行为不可预测。
这说明了我遇到的问题...
def y_at_x_first(x):
return x * 1.0
def y_at_x_second(x):
return x * 2.0
things = {
'first': {
'y_at_x': lambda x: y_at_x_first(x)
},
'second': {
'y_at_x': lambda x: y_at_x_second(x)
},
}
for thing in things:
# Add a new function that makes use of the first
things[thing]['y2_at_x'] = lambda x: things[thing]['y_at_x'](x)
numbers = list(range(5))
print('first',
list(map(things['first']['y_at_x'], numbers)),
' = ',
list(map(things['first']['y2_at_x'], numbers)))
print('second',
list(map(things['second']['y_at_x'], numbers)),
' = ',
list(map(things['second']['y2_at_x'], numbers)))
我期待它打印:
first [0.0, 1.0, 2.0, 3.0, 4.0] = [0.0, 1.0, 2.0, 3.0, 4.0]
second [0.0, 2.0, 4.0, 6.0, 8.0] = [0.0, 2.0, 4.0, 6.0, 8.0]
但它实际打印的内容是以下之间的随机选择:
first [0.0, 1.0, 2.0, 3.0, 4.0] = [0.0, 2.0, 4.0, 6.0, 8.0]
second [0.0, 2.0, 4.0, 6.0, 8.0] = [0.0, 2.0, 4.0, 6.0, 8.0]
和
first [0.0, 1.0, 2.0, 3.0, 4.0] = [0.0, 1.0, 2.0, 3.0, 4.0]
second [0.0, 2.0, 4.0, 6.0, 8.0] = [0.0, 1.0, 2.0, 3.0, 4.0]
这实际上是一个随机选择,多次运行代码并且它会发生变化(我认为它与未排序的字典有关,因此随机性来自于此)。
我认为这一定是我的引用的问题,因此我尝试用 copy.deepcopy()
包围所有函数引用,但问题仍然存在。
非常感谢任何帮助。 我知道其他方法可以实现我想要实现的目标,但我想知道这是否是我的理解或Python的问题。 有趣的是,在Python3中结果是随机的;在 Python2 中,结果始终是第二个选项(4.0 作为元素 4)。
最佳答案
问题出在这段代码中:
for thing in things:
# Add a new function that makes use of the first
things[thing]['y2_at_x'] = lambda x: things[thing]['y_at_x'](x)
您在 lambda 函数内使用了 thing
,但 Python 不会将此值“存储”在 lambda 函数内供以后使用。例如,如果我将 thing
更改为其他内容,当您调用该函数时,它会使用该值作为 thing
:
>>> thing = 'foo'
>>> things['first']['y2_at_x'](3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in <lambda>
KeyError: 'foo'
您可以通过确保按预期使用 thing
来避免此问题(即,在 for 循环运行时它将具有适当的值):
for thing in things:
# Add a new function that makes use of the first
f = things[thing]['y_at_x'] # thing will have the value of the key here
things[thing]['y2_at_x'] = lambda x: f(x)
通过访问循环中的函数对象,可以清楚地知道您正在使用什么对象,然后您可以在 lambda 函数中调用它。
您所看到的随机性确实与字典无序这一事实有关,因此不知道 first
或 second
是否先出现。
关于Python - 字典中函数的错误分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28490987/