首页 > 解决方案 > 需要帮助理解奇怪的替换行为

问题描述

考虑以下代码片段,其中我尝试替换两个二项式系数的乘积

from sympy import *
from sympy.abc import k, x
a = Wild('a')
b = Wild('b')

pattern = binomial(k,a)*binomial(k,b)
replacement = x

orgineel = binomial(k, 1, evaluate=False)*binomial(k, 1, evaluate=False)
orgineel.replace(pattern , replacement)

这返回

更换失败的图片

替换没有工作。但是,如果任一二项式系数的数字与 1 不同,它确实有效!例如下面的代码

a = Wild('a')
b = Wild('b')

pattern = binomial(k,a)*binomial(k,b)
replacement = x

orgineel = binomial(k, 1, evaluate=False)*binomial(k, 2, evaluate=False)
orgineel.replace(pattern , replacement)

退货

更换成功图片

我不明白为什么。

谁能向我解释为什么会发生这种情况或如何规避它?

为清楚起见:我知道第一个二项式系数简单地等于 k,但我想将它们保持在这种形式中,以便我可以将它们与一堆其他二项式一起替换。

标签: pythonpython-3.xsympy

解决方案


这是一个由未计算的表达式触发的错误,即binomial(k, 1, evaluate=False). 像这样的未计算对象很难在 SymPy 中使用,因为许多操作会导致它们隐式计算。在这种情况下,调用xreplace此行将触发评估: https ://github.com/sympy/sympy/blob/8daad340791cc41707cc1b2b989ce4a9b6c15e75/sympy/core/operations.py#L280

作为一种解决方法,您可以创建自己的二项式类,该类不评估并将其用于替换:

In [1]: class Binomial(Function):
   ...:     pass
   ...: 

In [2]: k = Symbol('k')
   ...: a = Wild('a')
   ...: b = Wild('b')

In [3]: expr = binomial(k, 1, evaluate=False)**2

In [4]: pattern = binomial(k, a)*binomial(k, b)

In [5]: expr.replace(pattern, x)
Out[5]: 
   2
⎛k⎞ 
⎜ ⎟ 
⎝1⎠ 

In [6]: expr.replace(binomial, Binomial).replace(pattern.replace(binomial, Binomial), x)
Out[6]: x

推荐阅读