考虑以下sympy代码:
from sympy import Add
from sympy.abc import x
t1 = 2+2*x
t2 = x
myeq = sp.UnevaluatedExpr(Add(sp.UnevaluatedExpr(t1), sp.UnevaluatedExpr(t2), evaluate=False))
# BUG! Will print: x + 2*x + 2
# Yet it should print: 2+2*x+x
print(myeq)
此代码段改编自this答案。那里的术语更简单,因此Add
保留了顺序。但是在这种情况下,如何使Add
保持顺序呢?
(备注:如果我们将术语分别更改为t1=x
和t2=x**2
,则我使用sp.UnevaluatedExpr
的方法有效,但是没有这些术语的原始答案没有。对于我的具体情况,甚至不使用sp.UnevaluatedExpr
也可以。)
答案 0 :(得分:1)
...但是更多缺少的功能。所有这些都已记录在案。
SymPy就是unevaluated的意思。
通过未评估表示其内部的值不会 与它外面的表达式进行交互以简化 输出。
在您的示例中,术语2*x
和x
并未像预期的那样被简化。
您看到的是SymPy不保留您输入术语的顺序。这是documented under the expression tree section。
交换操作
Add
和Mul
的参数存储在 任意(但一致!)顺序,独立于 输入订单。
这应该没问题,因为Add
和Mul
是可交换的。
但是,如果由于某种原因由于乘法的不可交换性而要保留输入的顺序,则可以这样做。
在SymPy中,您可以使用
Symbol('A', commutative=False)
创建非交换符号,并使用 非交换符号保持与输入相同)
到目前为止,似乎还没有非可交换加法。