Перебор списка для создания функций - PullRequest
1 голос
/ 06 апреля 2020

Я пытаюсь решить большую систему дифференциальных уравнений, используя solve_ivp.

from scipy import integrate
sol = integrate.solve_ivp(func_system, (0,100), initial_value_array, t_eval)

. func_system - это система дифференциальных уравнений, которая зависит от длины списка X:

X = ['a','b','c','d',...]

K1, K2, K3, K4 = [1, 2, 2, 1]

def dadt(X,t):
    return -K1*X[0]+K2*X[1]
def dbdt(X,t):
    return K2*X[0]-(K2+K3+K4)*X[1]
def dcdt (X,t):
    return ....
def dddt (X,t):
    return ....

и т. Д.

def func_system(X,t):
    return np.array([dadt(X,t), dbdt(X,t), dcdt(X,t), dddt(X,t)])

Поскольку X может быть очень длинным, я бы хотел перебрать список для создания имен функций. Например,

dxdt = ['d'+a+'dt' for a in X]

for i in range(len(dxdt)):
    def dxdt[i]:
        return something

, где я получаю "что-то" из кадра данных. Мой вопрос: можно ли перебирать список для создания имен функций?

Ответы [ 3 ]

2 голосов
/ 07 апреля 2020

Это то, что вы пытаетесь совершить sh?

Python 3.6.9 (default, Oct 17 2019, 06:42:36) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.2.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: X = ['a','b','c','d']                                                                                                                                                                                                              

In [2]: K1, K2, K3, K4 = [1, 2, 2, 1]                                                                                                                                                                                                      

In [3]: code = ['def d{symbol}dt(X, t): return "something"'.format(symbol=symbol) for symbol in X]                                                                                                                                         

In [4]: functions = {}                                                                                                                                                                                                                     

In [5]: for func in code: 
   ...:     exec(func, {}, functions) 
   ...:                                                                                                                                                                                                                                    

In [6]: functions                                                                                                                                                                                                                          
Out[6]: 
{'dadt': <function dadt(X, t)>,
 'dbdt': <function dbdt(X, t)>,
 'dcdt': <function dcdt(X, t)>,
 'dddt': <function dddt(X, t)>}

In [7]: functions['dadt'](1, 0)                                                                                                                                                                                                            
Out[7]: 'something'
2 голосов
/ 07 апреля 2020

Как уже предлагалось, вы можете просто использовать, например. продиктовать это. Не самое элегантное решение, но однозначно выполнимое и даже не столь уродливое, если все функции имеют одинаковую сигнатуру :

dispatch = {
  'dadt': lambda X, t: -K1*X[0]+K2*X[1],
  'dbdt': lambda X, t: K2*X[0]-(K2+K3+K4)*X[1],
  # you get the idea
}

# later, eg. to call dadt(my_vector, t):
rval = dispatch["dadt"](my_vector, t)

# or, if you want to have pretty functions eg. that you call often, functions
# are just values too:

dadt = dispatch["dadt"]
dadt(my_vector, t)
1 голос
/ 07 апреля 2020

Почему бы не использовать dict? Ключами будут имена и значения функций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...