Python`or`,`and`运算符优先级示例 [英] Python `or`, `and` operator precedence example

查看:177
本文介绍了Python`or`,`and`运算符优先级示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法在Python中产生显示布尔运算符优先级规则与短路评估相结合的示例.我可以使用以下方式显示运算符优先级:

I cannot produce example in Python which shows Boolean operator precedence rules combined with short circuit evaluation. I can show operator precedence using:

print(1 or 0 and 0)  # Returns 1 because `or` is evaluated 2nd.

但是当我将其更改为此时,就会出现短路问题:

But the issue with short circuiting shows up when I change it to this:

def yay(): print('yay'); return True
def nay(): print('nay')
def nope(): print('nope')
print(yay() or nay() and nope())  # Prints "yay\nTrue"

对于or之前的表达式为True的4种可能性中的每一种,它都是唯一的求值表达式.如果运算符优先级起作用,则应该打印"nay\nnope\nyay\nTrue""nay\nyay\nTrue"并短路,因为and应该被评估为第一.

For each of 4 possibilities when expression before or is True it is the only evaluated expression. If operator precedence works this should print "nay\nnope\nyay\nTrue" or "nay\nyay\nTrue", with short circuiting, because and should be evaluated 1st.

从此示例中想到的是,Python从左到右读取布尔表达式,并在知道结果的情况下结束该布尔表达式,而与运算符的优先级无关.

What comes to mind from this example is that Python reads boolean expression from left to right and ends it when result is known regardless of operator precedence.

我的错误在哪里或我错过了什么?请举一个例子,可以清楚地看到and是第1个值,而不是因为代码是从左向右解释的.

Where is my error or what am I missing? Please give an example where it's visible that and is evaluated 1st and it isn't due to code being interpreted from left to right.

推荐答案

您正在混淆运算符的优先级和评估顺序.

You are confusing operator precedence and evaluation order.

表达式r = x or y and z不会被评估为tmp = y and z; r = x or tmp,而是被评估为r = x or (y and z).该表达式是从左到右求值的,如果or的结果已经确定,则(y and z)根本不会求值.

The expression r = x or y and z is not evaluated as tmp = y and z; r = x or tmp, but just as r = x or (y and z). This expression is evaluated from left to right, and if the result of the or is already decided, then (y and z) will not be evaluated at all.

请注意,如果orand是函数,则会有所不同;在这种情况下,将在调用函数本身之前先评估函数的参数.因此,operator.or_(yay(), operator.and_(nay(), nope()))打印yaynaynope,即,它打印所有三个,但是仍然从左到右依次打印.

Note that it would be different if or and and were functions; in this case, the parameters of the functions would be evaluated before the function itself is called. Hence, operator.or_(yay(), operator.and_(nay(), nope())) prints yay, nay and nope i.e. it prints all three, but still in order from left to right.

您也可以将其推广到其他运算符.由于运算符优先级不同(使用(...)隐式和显式),以下两个表达式将产生不同的结果,但是两次都从左到右调用了函数.

You can generalize this to other operators, too. The following two expressions will yield different results due to the different operator precedence (both implicit and explicit by using (...)), but the functions are called from left to right both times.

>>> def f(x): print(x); return x
>>> f(1) + f(2) * f(3) / f(4) ** f(5) - f(6)         # 1 2 3 4 5 6 -> -4.99
>>> (f(1) + f(2)) * (((f(3) / f(4)) ** f(5)) - f(6)) # 1 2 3 4 5 6 -> -17.29

如评论中所指出的,虽然操作之间的术语是从左到右评估的,但实际操作是根据它们的优先级评估的.

As pointed out in comments, while the terms in between operations are evaluated from left to right, the actual operations are evaluated according to their precedence.

class F:
    def __init__(self,x): self.x = x
    def __add__(self, other): print(f"add({self},{other})"); return F(self.x+other.x)
    def __mul__(self, other): print(f"mul({self},{other})"); return F(self.x*other.x)
    def __pow__(self, other): print(f"pow({self},{other})"); return F(self.x**other.x)
    def __repr__(self): return str(self.x)
def f(x): print(x); return F(x)

这样,将表达式f(1) + f(2) ** f(3) * f(4)评估为123pow(2,3)4mul(8,4)add(1,32),即,术语从左到右进行评估向右(并压入堆栈),表达式的参数一经求值就立即求值.

This way, the expression f(1) + f(2) ** f(3) * f(4) is evaluated as 1, 2, 3, pow(2,3), 4, mul(8,4), add(1,32), i.e. terms are evaluated left-to-right (and pushed on a stack) and expressions are evaluated as soon as their parameters are evaluated.

这篇关于Python`or`,`and`运算符优先级示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆