我认为这个简短的代码应该更清楚地理解我的问题:
fs = []
for k in range(0, 10):
def f(x):
return x + 2*k
fs.append(f)
fs[0](1)
# expecting 1 but 19(=1+2*9)
如何让f
返回我想要的内容?请注意f
无法收到k
作为参数。
(我实际上要做的是准备multiple constraint functions that are fed to scipy.optimize.minimize)
答案 0 :(得分:5)
解决此问题的典型方法是执行以下操作:
def f(x, k=k):
return x + 2*k
在大多数情况下,这不应该影响你的“f不能接受k作为参数”条件,因为它不是必需的参数。
一种相关但不同的方法是将f
定义为循环。
def f(k, x):
return x + 2*k
然后在循环中使用functools.partial。
import functools
fs = []
for k in range(10):
fs.append(functools.partial(f, k))
在这种方法中,即使您尝试传递一个值,您的函数也不会接受k
的值。
答案 1 :(得分:2)
基本上问题在于,在这种情况下,变量k随循环迭代而不断变化。这意味着所有指向变量“k”的东西都始终指向相同的值。
有几种方法可以解决这个问题。这可能是最常见的。
def f(x, k=k):
# This sets k as a locally bound variable which is evaluated
# at the time the function is created.
return x + 2*k
不利的是,该解决方案将允许稍后的函数使用不同的k值调用新创建的函数。这意味着您可以致电f("cat","dog")
并获取"catdogdog"
作为回报。虽然这不是世界末日,但它肯定不是意图。
但是,您也可以这样做:
def f_maker(k):
# Create a new function whose variable "k" does not exist in outside scope.
def f(x):
return x + 2*k
return f
fs = []
for k in range(0, 10):
fs.append(f_maker(k))
fs[0](1)