如何将Sympy的“Mod()”转换为Python的“%”语法?

时间:2017-02-21 19:22:58

标签: python python-3.x sympy

我想知道如何将Sympy的“Mod()”转换为Python的百分号(%)的默认语法。我找不到任何“内置”功能(在Sympy包中)。我可以自己写一个,除了我希望简化结果。在我要创建的函数中,我意识到我不知道如何避免添加额外的括号。由于我想以最简化的形式使用它,我需要使用Sympy的简化。然后,这将撤消“Mod()”到“%”的转换。因此,如果没有一种简单的方法将Sympy的Mod转换为Python的“%”,请告诉我Sympy中有一种方法可以简化括号。我看了,我也找不到。我至少想要一种方法来删除多余的括号而不将“%”转换回“Mod”。

修改

这是一个例子,我想:

Mod(x + 1, 3)

成为:

(x+1)%3

但我不想要:

Mod(x, 3)

是:

(x)%3

我希望它是:

x%3

1 个答案:

答案 0 :(得分:1)

现在我已经做了一些调查自定义打印的同意选项,看起来它很容易实现:

from sympy.printing.precedence import precedence
from sympy.printing.str import StrPrinter

class MyPrinter(StrPrinter):
    def _print_Mod(self,expr):
        own_level = precedence(expr)
        args = (self.parenthesize(arg, own_level) for arg in expr.args)
        return "{} % {}".format(*args)

printer方法parenthesize采用表达式和"级别"其中level表示优先级阈值,导致它实际在参数周围添加括号,因此它只会在需要它们的操作周围放置括号:

from sympy.abc import x

printer = MyPrinter()
def test(expr):
    print(printer.doprint(expr))

>>> test(x%3)
x % 3
>>> test((x+1)%3)
(x + 1) % 3

从我的(极其有限)测试似乎表明此工作正常,另请参阅下面有关own_level的说明。

documentation for overriding printing所示,您只需覆盖Basic.__str__即可在打印表达式时使用自定义打印机:

from sympy import Basic

Basic.__str__ = lambda expr, printer=MyPrinter(): printer.doprint(expr)

>>> print(x%3)
x % 3

作为旁注 - Mod默认情况下不能执行此操作的原因是因为它显然是继承自Function

>>> issubclass(sympy.Mod, sympy.Function)
True

这就是为什么它在几乎所有的打印方法中显示为函数调用的原因,这也意味着模数具有与函数相同的优先级:

>>> precedence(x%3)
70
>>> f = sympy.Function("f")
>>> precedence(f(x))
70
>>> print( f(x)%x ) #so it thinks f(x) needs parens here
(f(x)) % x

如果您找到适当的优先级用于own_level,请与我分享,因为我希望更新我的答案。