Python - Создать список функций для цикла for
Я пытаюсь создать список функций. Например, если у меня есть функция, которая принимает два аргумента 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[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.) Какое наиболее питонное решение?
Я прошу прощения, если вопрос два слишком много вопрос мнения.
Спасибо!