Итеративное определение функций в 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
Другие вопросы по тегам