给定一个输出列表的函数,Python中是否可以为每个组件提取函数?

时间:2017-02-02 10:36:03

标签: python

例如,假设我有一个将R2映射到R2的向量函数,例如:

fun = lambda x1, x2: [x1**2 + 1, x2**2 - x1]

我喜欢允许我这样做的事情:

for f in components(fun):
    print(f(2,3))  # Print first 5, then 7

注意:我不会问如何迭代一个组件,这是微不足道的(对于f(2,3):)中的val,但是如何迭代计算每个组件的函数输出。这可能吗?

4 个答案:

答案 0 :(得分:1)

嗯,你可以做一些技巧,虽然你需要明确说明预期的组件数量,因为没有办法告诉Python函数会有多少输出(除非你做一些像“探测”函数一样的东西测试值,这也是一种可能性,但更复杂):

def components(fun, n):
    for i in range(n):
        yield lambda *args, **kwargs: fun(*args, **kwargs)[i]

然后你的循环可能是:

for f in components(fun, 2):
    print(f(2,3))

如果您想避免重复计算,可以使用某种记忆。在Python 3中,您可以使用lru_cache

from functools import lru_cache

def components(fun, n):
    # You can tune lru_cache with a maxsize parameter
    fun = lru_cache()(fun)
    for i in range(n):
        yield lambda *args, **kwargs: fun(*args, **kwargs)[i]

答案 1 :(得分:0)

我认为不可能按照你的要求去做,因为在这种情况下,没有两种不同的功能。它是一个以列表作为输出的函数,将两个参数作为输入。

你可以创建两个不同的函数,并在一个大函数中连接它,以获得你对两个独立函数的访问:

fun_1 = lambda x1: x1**2 + 1
fun_2 = lambda x1, x2: x2**2 - x1
fun = lambda x1, x2: [fun_1(x1), fun_2(x1, x2)]

答案 2 :(得分:0)

您需要一系列功能:

R2map = [lambda x: x+3, lambda x: x-4]

使这成为接受两个参数的函数:

R2 = lambda x,y: [R2map[0][x],R2map[1][y]]

如果你想要一个函数列表,而不是一个返回列表的函数,那么就这样做。

答案 3 :(得分:0)

我发现同情心将这些功能转换成了一个表达式,所以我最终做了以下事情:

from inspect import signature
import sympy

def components(function):
    # Determine number of argument function takes
    n_args = len(signature(function).parameters)
    # Allocate n symbols like x1, x2, ..., xn
    symbols = [sympy.Symbol("x"+str(i)) for i in range(1, n_args+1)]
    # Get list of expressions for the components of the input function
    expression_list = function(*symbols)

    # Convert each expression into a function and yield
    for expr in expression_list:
        yield lambda *args: sympy.lambdify(symbols, expr)(*args)

    return None

fun = lambda x1, x2: [x1**2 + 1, x2**2 - x1]

for f in components(fun):
    print(f(2,3))  # prints 5, 7