定义函数时评估变量

时间:2018-07-25 11:15:29

标签: python

有人能解释我为什么在评估列表中的函数时,这两个python代码块不能给我相同的结果:

第1块:

fct_list = []
theta = [[-2.95,0.001], [-0.5,0.511], [-0.1,0.51], [-2.95,0.001]]
for i in range(4):
     def fct(lcs):
         return some_func(lcs, beta=theta[i][0], sigma=theta[i][1])
     fct_list.append(fct)

第2块:

def fct_1(lcs):
    return some_func(lcs, beta=-2.95, sigma=0.001)

def fct_2(lcs):
    return some_func(lcs, beta=-0.5, sigma=0.511)

def fct_3(lcs):
    return some_func(lcs, beta=-0.1, sigma=0.51)

def fct_4(lcs):
    return some_func(lcs, beta=-2.95, sigma=0.001)
fct_list = [fct_1,fct_2,fct_3,fct_4]

似乎在第一种情况下不会评估参数,并且在执行函数时会使用内存中的theta值。

与第二种情况一样,我希望在函数中对beta和sigma的值进行硬编码,但是要使用在构建列表时评估的参数的值。有谁知道这是怎么做到的吗 ?

我目前的方法是将块2写入一个单独的文件中,以便在构建列表时对beta和sigma的数值进行硬编码。有没有更清洁的方法可以做到这一点?

2 个答案:

答案 0 :(得分:0)

我想问题是您正在重新定义每个函数 迭代步骤,也适用于先前的功能 在fct_list中... 内置的functools库实际上具有一个不错的功能供您使用(https://docs.python.org/2/library/functools.html#functools.partial):

from functools import partial

def some_func(x, beta, sigma):
    return [x , beta , sigma]

fct_list = []
theta = [[-2.95,0.001], [-0.5,0.511], [-0.1,0.51], [-2.95,0.001]]
for i in range(4):

     fct_list.append(partial(some_func, beta=theta[i][0], sigma=theta[i][1]))

答案 1 :(得分:0)

通过循环构建列表fct_list1时,变量i闭包,并在内部函数fct()中被“记住”。但是该变量i是通过引用记住的,因此,当您对其进行更改(并通过迭代将对其进行更改)时,最终值为3。参见示例,我在内部函数fct中添加了print:

fct_list1 = []
fct_list2 = []
theta = [[-2.95,0.001], [-0.5,0.511], [-0.1,0.51], [-2.95,0.001]]

def some_func(l, beta, sigma):
    print(l, beta, sigma)

for i in range(4):
    def fct(lcs):
        print(i)
        return some_func(lcs, beta=theta[i][0], sigma=theta[i][1])
    fct_list1.append(fct)

def fct_1(lcs):
    return some_func(lcs, beta=-2.95, sigma=0.001)

def fct_2(lcs):
    return some_func(lcs, beta=-0.5, sigma=0.511)

def fct_3(lcs):
    return some_func(lcs, beta=-0.1, sigma=0.51)

def fct_4(lcs):
    return some_func(lcs, beta=-2.95, sigma=0.001)

fct_list2 = [fct_1,fct_2,fct_3,fct_4]


for f in fct_list1:
    f(theta)

print('-' * 80)

for f in fct_list2:
    f(theta)

输出:

3
[[-2.95, 0.001], [-0.5, 0.511], [-0.1, 0.51], [-2.95, 0.001]] -2.95 0.001
3
[[-2.95, 0.001], [-0.5, 0.511], [-0.1, 0.51], [-2.95, 0.001]] -2.95 0.001
3
[[-2.95, 0.001], [-0.5, 0.511], [-0.1, 0.51], [-2.95, 0.001]] -2.95 0.001
3
[[-2.95, 0.001], [-0.5, 0.511], [-0.1, 0.51], [-2.95, 0.001]] -2.95 0.001
--------------------------------------------------------------------------------
[[-2.95, 0.001], [-0.5, 0.511], [-0.1, 0.51], [-2.95, 0.001]] -2.95 0.001
[[-2.95, 0.001], [-0.5, 0.511], [-0.1, 0.51], [-2.95, 0.001]] -0.5 0.511
[[-2.95, 0.001], [-0.5, 0.511], [-0.1, 0.51], [-2.95, 0.001]] -0.1 0.51
[[-2.95, 0.001], [-0.5, 0.511], [-0.1, 0.51], [-2.95, 0.001]] -2.95 0.001

解决方案之一是稍微修改循环中的代码:

for i in range(4):
    def fct(lcs, index):
        return some_func(lcs, beta=theta[index][0], sigma=theta[index][1])
    fct_list1.append(lambda lcs, index=i: fct(lcs, index))
相关问题