表示“ <”在自定义函数中不返回布尔值?

时间:2019-10-21 11:38:14

标签: python sympy

摘要

我针对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条件中的所有运算符通常求值为布尔值。

  • 为什么这不适用于<,>,<=,> =?
  • 有解决方案吗?
  • 如何确定其他语句是否也以异常结尾?

1 个答案:

答案 0 :(得分:1)

问题在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”的实例之间不支持