使用“exact=False”时 expr.replace() 的实际行为是什么

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

我一直在研究 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 sympy
1个回答
0
投票

从您所引用的

.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
 来限制匹配

https://docs.sympy.org/latest/modules/core.html#sympy.core.symbol.Wild

另请注意,对于像

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)
    
© www.soinside.com 2019 - 2024. All rights reserved.