摘要
我针对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条件中的所有运算符通常求值为布尔值。
答案 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”的实例之间不支持