«Биективно» применить список функций к списку аргументов - PullRequest
0 голосов
/ 06 января 2020

Скажем, у меня есть некоторые функции, определенные еще в коде; давайте используем две разные кривые PDF в качестве примера:

import numpy as np

# Gaussian 1
def fa(mu, sigsq, x):
    return ((np.sqrt(2*np.pi*sigsq))**(-1) 
            * np.exp((-0.5 * (x - mu + 1)**2)/sigsq))

# Gaussian 2
def fb(nu, omsq,  x):
    return ((np.sqrt(2*np.pi*omsq))**(-1) 
            * np.exp(-(0.5 * (x - nu - 1)**2)/omsq))

...

fs = [fa, fb, ...]

Применить список функций с одинаковым количеством аргументов к некоторым заданным легко:

fmap = lambda fns, *args: map(lambda fn: fn(*args), fns)

multipeak_gauss = lambda x: sum(list(fmap(fs, 0., 1., x)))

Теперь давайте каждый Функция имеет уникальный набор аргументов различного размера:

import numpy as np

# Gaussian
def fa(mu, sigsq, x):
    return ((np.sqrt(2*np.pi*sigsq))**(-1) 
            * np.exp((-0.5 * (x - mu + 1)**2)/sigsq))

# Maxwell-Boltzmann
def fb(a, x):
    return (np.sqrt(2/np.pi) 
            * (x**2 / a**3) 
            * np.exp(-(x**2)/(2*a**2)))

...

fs  = [fa,           fb,       ...]
ars = [[0., .1, 1.], [1., 1.], ...]

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

Пока что мое лучшее предположение:

specmap = lambda fns, *args: [fn(arg) for fn, arg in zip(fns, *args)]

Этот код сталкивается с очевидной проблемой, что он передает список в функцию, которая ожидает только простые аргументы. Интуиция подсказывает мне, что я могу каким-то образом «развернуть» каждый список в списке списков с помощью чего-то вроде

specmap = lambda fns, *args: [fn(ar for ar in arg) for fn, arg in zip(fns, *args)]

, хотя приведенный выше код явно неисправен, и я не знаю, как именно это можно сделать.

1 Ответ

0 голосов
/ 06 января 2020

Как обрисовано @hpaulj в комментариях, решением было «открыть» определенный список аргументов внутри функции:

specmap = lambda fns, args: [fn(*arg) for fn, arg in zip(fns, args)]

, сохраняя входной список наборов как список, а не как * список объектов.

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