有人能解释我为什么在评估列表中的函数时,这两个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的数值进行硬编码。有没有更清洁的方法可以做到这一点?
答案 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))