首页 > 解决方案 > 从(解析)Sympy结果中提取值的可靠方法

问题描述

我正在使用SymPy,一个用于符号数学的 Python 库,以减少以编程方式读取的不等式,例如

from sympy.solvers.inequalities import reduce_rational_inequalities

# In reality, these inequalities are read in programmatically
inequality1 = 'x - 0.5 >= 0.0'
inequality2 = '0.49 - x**2 >= 0.0'

listOfInequalities = [sympy.parse_expr(inequality1), sympy.parse_expr (inequality2)]

ReducedInequalities = reduce_rational_inequalities([listOfInequalities], x)

这会产生对应于 x 介于 0.5 和 0.7 之间的正确结果:

0.5≤∧≤0.7

或者,表示为字符串:

strReducedInequalities = str(ReducedInequalities)
\begin{equation*}(0.5 <= x) & (x <= 0.7)\end{equation*}

我的问题是,是否有一种可靠的方法来解析这样的结果以提取常量 0.5 和 0.7?我可以搜索结果 strReducedInequalities,或者可能使用正则表达式,以查找诸如 '(' 和 '<= x' 之类的字符串的位置以提取 0.5。但这似乎很脆弱:如果 SymPy 要更改其输出格式化,代码可能会中断。

更可靠的是遍历输出的结构化方式,例如 strReducedInequalities 可以表示为

[expression1, joiner, expression2]

在哪里

然后表达式 1 可能被分解为

[constant, inequality_type, variable]

在哪里

解决方案

以下是我如何实现来自@smichr的出色解决方案:

from sympy import *
from sympy.core.relational import Relational
x = symbols('x')
eq = solve([x >= 0.5, x <= 0.7])
[(i.rhs, i.rel_op, i.lhs) for i in [i.canonical for i in eq.atoms(Relational)]]

或者在我原来的问题中使用程序生成的列表方法:

from sympy import *
from sympy.core.relational import Relational
x = symbols('x')

# In reality, these inequalities are read in programmatically
inequality1 = 'x - 0.5 >= 0.0'
inequality2 = '0.49 - x**2 >= 0.0'

listOfInequalities = [parse_expr(inequality1), parse_expr (inequality2)]
eq = solve(listOfInequalities)
[(i.rhs, i.rel_op, i.lhs) for i in [i.canonical for i in eq.atoms(Relational)]]

使用任一方法的结果:

[(0.500000000000000, '>=', x), (0.700000000000000, '<=', x)]

标签: pythonparsingsympysymbolic-mathinequality

解决方案


如果关系已经解决,那么一侧有一个符号,另一侧有一个值,该canonical方法会将它们按顺序排列,因此符号在左侧:

>>> eq
(1/2 <= x) & (x <= 7/10)
>>> [(i.rhs, i.rel_op, i.lhs) for i in [i.canonical for i in eq.atoms(Relational)]]
[(7/10, '<=', x), (1/2, '>=', x)]

推荐阅读