从字符串中解析条件

Laz*_*Cat 5 python numpy eval python-2.7

我有两个 numpy 数组 a、b 和一个以下形式的字符串s = "1.5 * b if 2*a > 7 else a + b"

我想创建一个数组 c,它将以有效的方式评估数组上的字符串。

期望行为的示例:

a = np.array([1, 4])
b = np.array([3, 1])
s = "1.5 * b if 2*a > 7 else a + b"
print(my_eval(a, b, s))

[4, 1.5]
Run Code Online (Sandbox Code Playgroud)

正在考虑类似的事情 f = np.vectorize(eval(s)); map(a, b, f)

最好的方法是什么?表达式中的数组数量可以更大(但受到合理限制。

Eri*_*erd 0

我不能谈论效率,但您可以s在函数定义模板字符串中使用给定的字符串表达式,将其执行到本地字典中exec,将其矢量化为非ufunc表达式,然后在建议的my_eval函数中调用它:

import numpy as np


def my_eval(s, a, b):

    locals_dict = {}

    # Generates source code to define a new function from the given string.
    source = f"def f(a, b): return {s}"

    # Executes the function definition script into locals_dict.
    exec(source, globals(), locals_dict)

    # Defines a vectorized version of the newly defined function.
    f = np.vectorize(locals_dict["f"])

    # Applies the function.
    return f(a, b)


s = "1.5 * b if 2 * a > 7 else a + b"
a = np.array([1, 4]).astype(float)
b = np.array([3, 1]).astype(float)
c = my_eval(s, a, b)

print(c)
Run Code Online (Sandbox Code Playgroud)

可以修改它以处理可变数量的输入参数。例如,如下所示的内容最多可以处理 26 个不同的输入数组,每个数组对应字母表中的每个字母:

import numpy as np
from string import ascii_lowercase


def my_eval(s, *args):

    locals_dict = {}

    # Generates source code to define a new function from the given string.
    params = ", ".join(list(ascii_lowercase[0:len(args)]))
    source = f"def f(*args): {params} = args; return {s}"

    # Executes the function definition script into locals_dict.
    exec(source, globals(), locals_dict)

    # Defines a vectorized version of the newly defined function.
    f = np.vectorize(locals_dict["f"])

    # Applies the function.
    return f(*args)
Run Code Online (Sandbox Code Playgroud)