Итеративное определение функций в Python
Я схожу с ума с такой проблемой:
У меня есть список строк, представляющих функции (для 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'). Как я могу сохранить различные определения функций?
1 ответ
Ваш комментарий:
но две функции всегда дают один и тот же результат (соответствующий последнему определению 'sos')
Это большая подсказка, что вы, вероятно, столкнулись с этой распространенной ошибкой!
Ваш код не работает, поэтому я не могу это проверить, но в нем явно есть эта ошибка. Есть несколько способов исправить это, в том числе с помощью 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