如何定义更改内部值的多个函数?

时间:2015-02-25 16:02:11

标签: python

我认为这个简短的代码应该更清楚地理解我的问题:

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

2 个答案:

答案 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)