从(解析)Sympy 结果中提取值的可靠方法

Reliable way to extract values from (parse) Sympy result

我正在使用 SymPy, a Python library for symbolic mathematics, to reduce inequalities 以编程方式读入,例如

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]

哪里

然后 expression1 可能会分解为

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

如果关系已经解决,那么一侧有一个符号,另一侧有一个值,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)]