【问题标题】:iterative definition of functions in Python [duplicate]Python中函数的迭代定义[重复]
【发布时间】:2016-08-24 14:07:21
【问题描述】:

我被这种问题弄疯了:

我有一个表示函数的字符串列表(用于 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'定义)。如何保留不同的函数定义?

【问题讨论】:

  • "但是这两个函数总是给出相同的结果(对应于最后一个'sos'定义)"这是因为i是按名称捕获的,所以当@ 987654327@ 被调用 i 将具有最终值。见here

标签: python list function redefinition


【解决方案1】:

您的评论:

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

你可能遇到过这个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

【讨论】:

  • 非常感谢您的提示!我知道这是由于“后期绑定关闭”。很好的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-13
  • 2020-01-01
  • 1970-01-01
  • 2021-07-20
  • 2021-05-14
  • 2020-11-16
  • 1970-01-01
相关资源
最近更新 更多