首页 > 解决方案 > Sympify“<”在自定义函数中不返回布尔值?

问题描述

概括

我为 sympy 自行编写的 if-then-else 条件不适用于某些布尔值。

代码 (注意:分段不是我的选择,这里建议https://stackoverflow.com/a/38858444/5626139

from sympy import Function

class ifte(Function):
    nargs = 3

    @classmethod
    def eval(cls, a, b, c):
        if a > 0:
            return b
        else:
            return c

这部分工作,例如这三个布尔值:

>>> print(ifte('1+2 and True and 1 != 2', 'b', 'c'))
b

问题

为什么 0<1 的行可以正确评估?

>>> print(ifte('0==1', 'b', 'c'))
b
>>> print(ifte('0<1', 'b', 'c'))
TypeError: 
A Boolean argument can only be used in Eq and Ne; all other
relationals expect real expressions.

if 条件中的所有运算符通常计算为布尔值。

标签: pythonsympy

解决方案


该问题在以下期间触发if

from sympy import Function

class ifte(Function):
    nargs = 3

    @classmethod
    def eval(cls, a, b, c):
        if a > 0:  # <-- PROBLEM HERE
            return b
        else:
            return c

它与得到的type有关a。由于这取决于 中的表达式a,因此您会观察到不同表达式的不同行为。特别是,对于 的某些值a,这将是sympy.logic.boolalg.*。如果是这种情况,则未定义__gt__方法(在使用运算符时调用),并且您会看到观察到的错误。>对于其他一些值,这将是一个简单的bool,为其__gt__定义方法并且代码按您期望的方式工作。

要解决这个问题,只需删除> 0比较,即

from sympy import Function

class ifte(Function):
    nargs = 3

    @classmethod
    def eval(cls, a, b, c):
        if a:
            return b
        else:
            return c

或者,更简单地说:

from sympy import Function

class ifte(Function):
    nargs = 3

    @classmethod
    def eval(cls, a, b, c):
        return b if a else c
print(ifte('1+2 and True and 1 != 2', 'b', 'c'))
# b
print(ifte('1==0', 'b', 'c'))
# c
print(ifte('1>0', 'b', 'c'))
# b
print(ifte('1<0', 'b', 'c'))
# c

请注意,您收到的错误消息取决于您拥有的 SymPy 版本,但原理是相同的。例如,在1.1.1我得到的版本中:

TypeError:“BooleanTrue”和“int”的实例之间不支持“>”


推荐阅读