仅用符号替代顶层

问题描述 投票:0回答:1

我有一个“sympy.subssubstitutes too much”问题。

基本上,我已经定义了从sympsi Operator类继承的costum sympy类。我们称其中之一为Tree。该树又包含例如符号,并具有与之关联的某些代数规则,这些规则我已通过__add__等定义。

然后我使用包含这些Tree对象的数学表达式。例如:

x = symbols('x')
y = symbols('y')
z = symbols('z')
tree1 = Tree(x, y)

cool_quantity = x + y + tree1

我现在想替换其中一个符号,例如x,带有另一个符号,例如z

cool_quantity_subs = cool_quantity.subs({x: z})

问题:我注意到,当我这样做时,替换也完成了[[inside Tree对象(请参见下面的最小工作示例)。我认为原因是通过从sympy.Expr继承将属性定义为自由符号。

问题:有没有办法仅在“顶层”进行符号替换?那就是替换表达式中直接包含的所有符号,而不替换自定义对象中的所有符号?

完整的最小工作示例

(不幸的是,必须运行sympsi,但是我认为问题对于使用自定义类的sympy来说是通用的。也许比我更了解sympy的人可以提出这样一个自定义的示例从本地sympy类继承的树类):from sympy import symbols from sympsi import Operator class Tree(Operator): @property def a(self): return self.args[0] @property def b(self): return self.args[1] def __new__(cls, *args, **hints): return Operator.__new__(cls, *args, **hints) x = symbols('x') y = symbols('y') z = symbols('z') tree1 = Tree(x, y) cool_quantity = x + y + tree1 cool_quantity_subs = cool_quantity.subs({x: z}) print(cool_quantity) # x + y + Tree(x,y) print(cool_quantity_subs) # y + z + Tree(z,y)
symbols sympy substitution
1个回答
0
投票
这里是通过定义自定义替换函数起作用的解决方案。不利的一面是,必须手动检查不应该遍历替换的每个对象。可能会有更清洁的解决方案。

from functools import reduce def special_subs(expr, to_rep, to_sub): terms = [] for term in expr.args: if term == to_rep: term = to_sub elif not isinstance(term, Tree): if len(term.args)>0: term = special_subs(term, to_rep, to_sub) terms.append(term) return expr.func(*terms)

应用于此问题中的最小工作示例

from sympy import symbols from sympsi import Operator from functools import reduce class Tree(Operator): @property def a(self): return self.args[0] @property def b(self): return self.args[1] def __new__(cls, *args, **hints): return Operator.__new__(cls, *args, **hints) x = symbols('x') y = symbols('y') z = symbols('z') tree1 = Tree(x, y) cool_quantity = x + y + tree1 cool_quantity_subs = cool_quantity.subs({x: z}) cool_quantity_special_subs = special_subs(cool_quantity, x, z) print(cool_quantity) # x + y + Tree(x,y) print(cool_quantity_subs) # y + z + Tree(z,y) print(cool_quantity_special_subs) # y + z + Tree(x,y)

© www.soinside.com 2019 - 2024. All rights reserved.