我一直在研究 SymPy 文档。我在主题->基础->核心->基础部分找到了以下内容:
>>> e = x**(1 + y)
>>> (x**(1 + y)).replace(x**(1 + a), lambda a: x**-a, exact=False)
x
>>> (x**(1 + y)).replace(x**(1 + a), lambda a: x**-a, exact=True)
x**(-x - y + 1)
>>> (x**y).replace(x**(1 + a), lambda a: x**-a, exact=False)
x
>>> (x**y).replace(x**(1 + a), lambda a: x**-a, exact=True)
x**(1 - y)
此行为似乎与 expr.replace() 的其余文档不一致。有大侠可以详细说明一下这些输出吗?
我希望第一个输出例如是:x**(-y)
这里是文档中出现上一个示例的位置的链接。就在3.1节之后,引入“exact=False”时
.replace
方法示例中的早期块中,a
是
Wild
(2.1 模式 -> expr),
x
和
y
是基本符号(初始)设置)
>>> from sympy.abc import x, y # initial setup
>>> a, b = map(Wild, 'ab') # 2.1
>>> srepr((a, b, x, y))
"(Wild('a'), Wild('b'), Symbol('x'), Symbol('y'))"
文档谈到了exact
论点
将此设置为更清楚地说,
False
接受0
的匹配;设置时True
接受所有包含0
的匹配项。
exact=True
会阻止
0
匹配
Wild
>>> sympify(0).replace(Wild('w'), 5, exact=False)
5
>>> sympify(0).replace(Wild('w'), 5, exact=True)
0
>>> f(0).replace(f(a), lambda a: f(a + 1), exact=False)
f(1)
>>> f(0).replace(f(a), lambda a: f(a + 1), exact=True)
f(0)
给定示例(以及一般情况下)中的替换变得令人困惑,因为 SymPy 可以进行看起来奇怪的匹配,例如将 1
简单替换为
x**(1+a)
,从而有效地分解表达式
>>> sympify(1).replace(x**(1 + a), lambda a: x**-a) # a: -1 -> x**1
x
>>> x.replace(x**(1 + a), lambda a: x**-a, exact=False) # a: 0 -> x**-0
1
>>> x.replace(x**(1 + a), lambda a: x**-a, exact=True) # doesn't match
x
您可以添加 map=True
参数来查看结果映射(返回
(result, match_dict)
的元组),突出显示意外的
1:x
映射
>>> (x**(1 + y)).replace(x**(1 + a), lambda a: x**-a, map=True, exact=False)[1]
{x: 1, 1: x}
>>> (x**(1 + y)).replace(x**(1 + a), lambda a: x**-a, map=True, exact=True)[1]
{1: x, x**(x + y): x**(-x - y + 1)}
我认为这个例子并没有足够清楚地表明它希望有人熟悉Wild
,并直接展示一些可能的奇怪匹配..而
Wild
的文档立即建议使用它的
exclude
和
properties
来限制匹配
2.2 这样的模式。 pattern -> func,仅将通配值传递给 lambda
obj.replace(pattern(wild), lambda wild: expr(wild))
例如,我们可以提供一个属性 a
不能是
-1
>>> sympify(1).replace(x**(1 + a), lambda a: x**-a) # a: -1 -> x**1
x
>>> sympify(1).replace(x**(a - 5), lambda a: a) # a: 5
5
>>> a = Wild('a', properties=[lambda a: a!=-1]) # don't match -1
>>> sympify(1).replace(x**(1 + a), lambda a: x**-a) # doesn't match
1
从根本上说,.replace()
或
.match()
与不受限制的
Wild
是让自己陷入失败,而包含
exact
仅用于处理许多意外比赛中的特殊情况
也许找到了匹配的
y
?
>>> a = Wild('a', properties=[lambda a: a.is_Symbol]) # constraint
>>> (x**(1 + y)).replace(x**(1 + a), lambda a: x**-a)
x**(-y)
或反转电源
>>> (x**(1 + y))**-1 # trivial
x**(-y - 1)
>>> (x**(1 + y)).replace(Pow, lambda a, b: a**-b) # unpack Pow
x**(-y - 1)