我正在尝试创建一个函数列表。例如,如果我有一个接受两个参数 f(x,y) 的函数,我想创建一个函数列表 f(x),例如 [f(x,0), f(x,1), f(x ,2), f(x,3)]。
这是一个人为的例子:给定 f(x,i) = x ** i。制作一个列表 [f(x,0), f(x,1), f(x,2), f(x,3)],其中列表中的函数只接受一个参数。因此,如果列表名为“a”,则可以将函数调用为
a[index](x)
这是我对这个问题进行编码的尝试。
n = 4
def func_creator_1(n):
func_list = list()
for i in range(n):
def func(x):
return x ** i
func_list.append(func)
return func_list
f_list_1 = func_creator_1(n)
def func_creator_2(i):
def func(x):
return x ** i
return func
f_list_2 = [func_creator_2(i) for i in range(n)]
def func_creator_3(n):
def func_outer(i):
def func(x):
return x ** i
return func
func_list = [func_outer(i) for i in range(n)]
return func_list
f_list_3 = func_creator_3(n)
def func_creator_4(n):
def func_x_i(x,i):
return x ** i
return [lambda x: func_x_i(x,i) for i in range(n)]
f_list_4 = func_creator_4(n)
def func_creator_5(n):
return [lambda x: x**i for i in list(range(n))]
f_list_5 = func_creator_5(n)
接下来,我将变量 x 分配给 2 并打印输出。n 已经分配给 4,以便它可以被方法 2 下面的列表理解使用。
x = 2
print('function\tmethod 1\tmethod 2\tmethod 3\tmethod 4\tmethod 5')
print('-'*90)
for c, f_tuple in enumerate(zip(f_list_1, f_list_2, f_list_3, f_list_4, f_list_5)):
f1, f2, f3, f4, f5 = f_tuple
print('{}^{}:\t\t{}\t\t{}\t\t{}\t\t{}\t\t{}\n'.format(
x, c, f1(x), f2(x), f3(x), f4(x), f5(x)))
这是输出:
function method 1 method 2 method 3 method 4 method 5
2^0: 8 1 1 8 8
2^1: 8 2 2 8 8
2^2: 8 4 4 8 8
2^3: 8 8 8 8 8
除了格式在控制台上看起来更好......
无论如何,在我看来,方法 1 是最易读的,并且代表了我将如何编码,但它失败了。我是 python 初学者,但我的猜测是,当创建列表中的函数时,变量“i”是某种指针,因此所有列表函数都引用相同的内存位置,在退出循环时,有值为 3。
方法 2 成功,但我不喜欢在函数之后必须有一个列表理解。如果我更改了 n,我将不得不同时调用 func_creator_2 并重做列表推导。
方法 3 只是我将方法 2 函数和列表理解步骤捆绑到一个函数中。它有效,并且只解决了我对方法 2 的抱怨,但它很难看。
方法4是另一种尝试......
在方法 5 中,我尝试“复制”或使“i”变量更永久。我会喜欢这个工作,因为它很干净,但它也失败了。
所以,在这一切之后,我有两个问题:
1.) 为什么方法 1、4 和 5 会失败?
2.) 什么是最 Pythonic 的解决方案?
如果问题二是一个过多的意见问题,我深表歉意。
谢谢!