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

给定一个输出列表的函数,在Python中是否可以为每个组件提取一个函数?,python,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 注意:我不是问如何迭代one out的组件,这很简单(对于f(2,3)中的val),而是问如何迭代计算输出中每个组件的函数。这可能吗?我认为不可能按你的要求去做,因为在这种情况下,没

例如,假设我有一个向量函数映射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

注意:我不是问如何迭代one out的组件,这很简单(对于f(2,3)中的val),而是问如何迭代计算输出中每个组件的函数。这可能吗?

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

您可以创建两个不同的函数,并将其连接到一个大函数中,以获得访问两个单独函数的内容:

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)]

您可以做一些技巧,尽管您需要显式地说明预期的组件数量,因为无法知道Python函数将有多少输出(除非您使用测试值“探测”函数,这也是一种可能性,但更复杂):

那么您的循环可以是:

for f in components(fun, 2):
    print(f(2,3))
如果您想避免重复计算,可以使用某种形式的记忆。在Python 3中,您可以使用:


我发现Symphy将这些函数转换为Symphy表达式列表,因此我最终执行了以下操作:

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

你能提供预期的输入和预期的输出吗?不确定你的意思。post包括示例功能和所需的打印输出。在两次迭代中,我希望函数f首先是x1^2+1,然后是x2^2-x1。这很难作为示例输出,因为如果您打印(f),Python只打印函数的内存地址。在这种情况下,您不是仍然只执行整个函数两次并获得不同的值吗?@skirebattie是的,但是如果这不是您想要的,我不确定它是什么。我的意思是,你想要有两个不同的、独立的函数,但是当其中一个被计算时,该值以某种方式被“缓存”,并在调用时被另一个使用?我不知道提问者想要什么;)我只是在检查。@skirebattie噢,对不起!我把你错当成了OP:S
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]
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