在Python中编写一个双不等式时,操作符的优先级是什么(在代码中显式显示,对于数组,如何重写它?)

2024-05-14 19:56:07 发布

您现在位置:Python中文网/ 问答频道 /正文

当我要求类似的东西时,按顺序执行的具体代码是什么

>>> 1 <= 3 >= 2
True

如果这两个不等式的优先级相等,而且只是它们的求值顺序,为什么第二个不等式的函数是(3 >= 2),而不是(True >= 2)

例如,考虑一下

>>> (1 < 3) < 2
True

>>> 1 < 3 < 2
False

将第二个语句扩展为这两个语句的and只是Python中一个纯粹的语法捷径吗?

我可以改变一个类的这种行为吗,这样a <= b <= c就可以扩展到不同的地方了?看起来是这样的

a (logical operator) b (logical operator) c 
    --> (a logical operator b) and (b logical operator c)

但真正的问题是如何在代码中实现这一点。

我很好奇,这样我就可以在我自己的一些类中复制这种__lt____gt__行为,但是我对如何保持中间参数不变感到困惑。

下面是一个具体的例子:

>>> import numpy as np

>>> tst = np.asarray([1,2,3,4,5,6])

>>> 3 <= tst
array([False, False,  True,  True,  True,  True], dtype=bool)

>>> 3 <= tst <= 5
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/home/ely/<ipython-input-135-ac909818f2b1> in <module>()
----> 1 3 <= tst <= 5

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

最好重写它,这样它也能“工作”在数组中,如下所示:

>>> np.logical_and(3 <= tst, tst <= 5)
array([False, False,  True,  True,  True,  False], dtype=bool)

添加以澄清

在评论中表明我在解释这个问题上做得很差。以下是一些澄清性的评论:

1)我不是在寻找一个简单的解释,解释程序在两个链式不等式之间弹出一个and。我早就知道了,上面这么说。

2)对于我想要做的事情,考虑一下with语句(link)。以下内容:

with MyClass(some_obj) as foo:
    do_stuff()

打开包装

foo = MyClass(some_obj)
foo.__enter__()
try:
    do_stuff()
finally:
    foo.__exit__()

因此,通过适当地编写MyClass,我可以在with语句中做许多特殊的事情。

我在问是否有一个类似的代码解压链式不等式,通过它我可以截取它在做什么,并将它重定向到使用数组式逻辑运算符,而不是仅针对我关心的类。

我觉得我的问题很清楚,尤其是例子,但希望这能让它更清楚。


Tags: and代码falsetruefoo顺序withnp
3条回答

but the real question is how this gets implemented in code.

你的意思是解释程序如何转换它还是什么?你已经说过了

a (logical operator) b (logical operator) c 
    --> (a logical operator b) and (b logical operator c)

所以我不知道你在问什么 好吧,我想起来了:不,不能重写从a < b < c(a < b) and (b < c)IIUC的扩展。


I'm curious so that I can replicate this kind of __lt__ and __gt__ behavior in some of my own classes, but I am confused about how this is accomplished holding the middle argument constant.

这取决于表达式a < b < c中的abc中的哪一个是您自己类的实例。实现您的__lt____gt__和方法有一些方法,但是documentation指出:

There are no swapped-argument versions of these methods (to be used when the left argument does not support the operation but the right argument does)

所以,如果你想Int < MyClass < Int,你就没运气了。您至少需要MyClass < MyClass < Something(因此类的实例位于展开表达式中每个比较的LHS上)。

两者具有相同的优先级,但根据documentation从左到右进行计算。形式为a <= b <= c的表达式被扩展为a <= b and b <= c

我不完全确定您要查找的是什么,但快速反汇编显示a < b < c不是编译成与a < b and b < c相同的字节码的

>>> import dis
>>>
>>> def f(a, b, c):
...     return a < b < c
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_FAST                1 (b)
              6 DUP_TOP
              7 ROT_THREE
              8 COMPARE_OP               0 (<)
             11 JUMP_IF_FALSE_OR_POP    21
             14 LOAD_FAST                2 (c)
             17 COMPARE_OP               0 (<)
             20 RETURN_VALUE
        >>   21 ROT_TWO
             22 POP_TOP
             23 RETURN_VALUE
>>>
>>> def f(a, b, c):
...     return a < b and b < c
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_FAST                1 (b)
              6 COMPARE_OP               0 (<)
              9 JUMP_IF_FALSE_OR_POP    21
             12 LOAD_FAST                1 (b)
             15 LOAD_FAST                2 (c)
             18 COMPARE_OP               0 (<)
        >>   21 RETURN_VALUE

编辑1:进一步挖掘,我认为这是numpy的奇怪之处或错误之处。考虑一下这个示例代码,我认为它可以如您所期望的那样工作。

class Object(object):
    def __init__(self, values):
        self.values = values
    def __lt__(self, other):
        return [x < other for x in self.values]
    def __gt__(self, other):
        return [x > other for x in self.values]

x = Object([1, 2, 3])
print x < 5 # [True, True, True]
print x > 5 # [False, False, False]
print 0 < x < 5 # [True, True, True]

编辑2:实际上这并不能“正常”工作。。。

print 1 < x # [False, True, True]
print x < 3 # [True, True, False]
print 1 < x < 3 # [True, True, False]

我认为这是在第二次比较1 < x < 3时将布尔值与数字进行比较。

编辑3:我不喜欢从gt、lt、gte、lte特殊方法返回非布尔值的想法,但根据Python文档,它实际上不受限制。

http://docs.python.org/reference/datamodel.html#object.lt

By convention, False and True are returned for a successful comparison. However, these methods can return any value...

相关问题 更多 >

    热门问题