我有一个需要替换的多个变量的表达式.问题是要替换的一些表达式还包含需要替换的变量实例.
from sympy import *
from sympy.abs import a,b, x,y
expr = a + b
replace = [[a, x+y], [b, 2*a]]
expr.subs(replace) # 2*a + x + y, I want 3*x + 3*y
Run Code Online (Sandbox Code Playgroud)
如果替换列表的顺序正确,它将按顺序应用每个替换,但在我的实际应用程序中,我不知道哪个顺序是合适的:
expr.subs(reversed(replace)) # 3*x + 3*y
Run Code Online (Sandbox Code Playgroud)
我可以通过应用替代n次要么强制替代expr或者replace,但这似乎浪费计算:
result = expr
for _ in replace:
# Applying n times
result = result.subs(replace)
Run Code Online (Sandbox Code Playgroud)
我希望有一个recursive选项subs,但这似乎不存在.有更好的选择吗?
如果按正确顺序执行,则将以迭代方式执行替换(除非您使用subs(replacement, simultaneous=True),它会立即执行所有替换).
您的问题是正确订购替换品.你想要的是拓扑式的替代品.即,每次更换处于图中的节点,并且存在从一个边缘(old1, new1)到(old2, new2)如果new1包含old2(即,应当先被替换).
SymPy拥有的实现topological_sort在sympy.utilities.iterables.它采用顶点列表和边缘列表(顶点元组).说你有
replace = [(y, z + 1), (x, y + z), (z, a)]
Run Code Online (Sandbox Code Playgroud)
我们可以创建一个边缘列表
from itertools import combinations
edges = [(i, j) for i, j in permutations(replace, 2) if i[1].has(j[0])]
Run Code Online (Sandbox Code Playgroud)
对此进行排序
>>> from sympy import default_sort_key, topological_sort
>>> topological_sort([replace, edges], default_sort_key)
[(x, y + z), (y, z + 1), (z, a)]
Run Code Online (Sandbox Code Playgroud)
第三个论点topological_sort是用来打破关系的关键.由于SymPy对象没有在它们上定义的隐式排序(<并且通常会>提高TypeError),因此调用了一个排序键实现default_sort_key,它提供了SymPy对象的规范和一致(但任意)排序.
在404所示的情况下,会出现无限循环,topological_sort会提醒您有一个循环
>>> replace = [(x, y+1), (y, x+1)]
>>> edges = [(i, j) for i, j in permutations(replace, 2) if i[1].has(j[0])]
>>> topological_sort([replace, edges], default_sort_key)
Traceback (most recent call last):
File "<ipython-input-51-72f3bfcfd4ad>", line 1, in <module>
topological_sort([replace, edges], default_sort_key)
File "/Users/aaronmeurer/Documents/Python/sympy/sympy/sympy/utilities/iterables.py", line 882, in topological_sort
raise ValueError("cycle detected")
ValueError: cycle detected
Run Code Online (Sandbox Code Playgroud)
老实说,这应该subs通过关键字参数直接实现.请参阅https://github.com/sympy/sympy/issues/6257.
| 归档时间: |
|
| 查看次数: |
1365 次 |
| 最近记录: |