Python中函数的迭代定义

时间:2016-08-24 14:07:22

标签: python list function redefinition

我对这类问题感到疯狂:

我有一个表示函数的字符串列表(对于eval),我首先需要用泛型x[0], x[1],...替换变量。

前段时间我发现我可以使用subs()执行此操作。然后我需要生成一个函数列表(在SciPy中定义约束最小化)。 我正在尝试类似的事情:

el=[budget.v.values()[0],silly.v.values()[0]] # my list of string/equations

fl=[]
for i in range(len(el)):
    def sos(v):
        vdict = dict(zip(q.v.values(),v)) 
        return eval(el[i]).subs(vdict)
    fl.append(sos) 
    del sos # this may be unnecessary

fl的结果是:

[<function sos at 0x19a26aa28>, <function sos at 0x199e3f398>]

但这两个函数总是给出相同的结果(对应于最后的'sos'定义)。如何保留不同的函数定义?

1 个答案:

答案 0 :(得分:2)

您的评论:

  

但这两个函数总是给出相同的结果(对应于最后的&#39; sos&#39;定义)

您可能会遇到这个common gotcha,这是一个很大的线索!

您的代码不是以可运行的形式存在,因此我无法对此进行验证,但显然存在此错误。有多种方法可以解决此问题,包括使用functools.partial,如第一个链接中所述。

例如(未经测试,因为您的代码不能按原样运行):

import functools

for i in range(len(el)):
    def sos(i, v):
        vdict = dict(zip(q.v.values(),v)) 
        return eval(el[i]).subs(vdict)
    fl.append(functools.partial(sos, i))

鉴于此,您现在可以重构此代码以避免重新定义循环内的函数:

def sos(i, v):
    vdict = dict(zip([2], v))
    return eval(el[i]).subs(vdict)

for i in range(len(el)):
   fl.append(functools.partial(sos, i))

为您提供完整且可运行的示例:

import functools

def add_x(x, v):
    return x + v

add_5 = functools.partial(add_x, 5)
print add_5(1)

产地:

6