Python运算符优先级

Python运算符优先级,python,expression,operator-precedence,Python,Expression,Operator Precedence,Python文档说*和/具有相同的优先级。 我知道python中的表达式是从左到右计算的 我可以依赖它并假设j*j/m总是等于(j*j)/m 避免使用括号? 如果是这样的话,我能假设这适用于一般具有相同优先级的运算符吗 附:这个问题对我来说很好, 我是在阅读不带括号的纯整数代码(如上面的示例)时找到它的, 这在当时我看来非常可疑。是的-具有相同优先级的不同运算符保持关联;也就是说,将对最左边的两个项目进行操作,然后是结果和第三个项目,依此类推 一个例外是**运算符: >>>

Python文档说
*
/
具有相同的优先级。
我知道python中的表达式是从左到右计算的

我可以依赖它并假设
j*j/m
总是等于
(j*j)/m
避免使用括号?
如果是这样的话,我能假设这适用于一般具有相同优先级的运算符吗


附:这个问题对我来说很好, 我是在阅读不带括号的纯整数代码(如上面的示例)时找到它的,
这在当时我看来非常可疑。

是的-具有相同优先级的不同运算符保持关联;也就是说,将对最左边的两个项目进行操作,然后是结果和第三个项目,依此类推

一个例外是
**
运算符:

>>> 2 ** 2 ** 3
256
此外,比较运算符(
=
,等等)不会以关联的方式运行,而是将
x[cmp]y[cmp]z
转换为
(x[cmp]y)和(y[cmp]z)
简短回答:是

同一框中的运算符具有相同的优先级。除非明确给出语法,否则运算符是二进制的。同一框中的运算符从左到右分组(除了比较,包括测试,它们都具有相同的优先级和从左到右的链…以及指数运算,它们从右到左分组)

换句话说,您的问题的答案是肯定的,具有相同优先级的运算符将从左到右分组,除了:

和指数:

>>> 2 ** 2 ** 3
256
>>> (2 ** 2) ** 3
64
>>> 2 ** (2 ** 3)
256
此外,在赋值中,右手边在左手边之前求值:

>>> x = 1
>>> y = x = 2
>>> y
2

但是,如果它对你(编码员)来说是不明确的,并且一定是因为你必须问,那么预计它对读者来说至少也是不明确的,并且为了清晰起见浪费了几个八位字节

如果您碰巧是一名编译器,那么依赖优先规则是非常好的

添加了对评论的回复

对于阅读代码的人,如果遇到需要外部咨询才能确定的歧义,您应该假设下一位读者的理解力不如您,并为他们节省解析相同构造的工作量和可避免的人为错误,并为他们添加括号

碰巧的是,即使是被接受的答案也是不正确的(在原理上,而不是效果上,见其第一条评论),这一点我并不知道,而且投票支持它的人中也有一小部分人不知道

至于关于基础代数的陈述,OP中使用的具体例子很有启发性。无论运算符优先级如何,表达式
j*(j/m)
在代数上与
(j*j)/m
相同。不幸的是,Python代数只是“柏拉图理想”代数的近似值,根据
j
m
的大小,它可能会对任何一种形式产生错误的答案。例如:

>>> m = 1e306
>>> m
1e+306
>>> j = 1e307
>>> j
9.9999999999999999e+306
>>> j / m
10.0
>>> j*j
inf
>>> j * (j / m)
1e+308
>>> (j * j) / m
inf
>>> ((j * j) / m) == (j * (j/m))
False
因此Python(和我的FPU)准代数的恒等式属性确实不成立。在您的机器上,这可能与以下情况不同:

浮点数被实现 在C中使用double。所有赌注都在 除非你碰巧碰上了,否则精度会下降 了解你正在使用的机器


可以说,人们没有必要在溢出的毛茸茸的边缘上工作,这在某种程度上是正确的,但从上下文中删除,这个表达是不确定的,因为一个操作顺序是不确定的,另一个操作顺序是“正确的”。

“显式优于隐式。”,“面对歧义,拒绝猜测的诱惑。”-PEP 20british:如果您正在阅读“仅限整数的代码”,那么您会遇到一个更大的问题:打算使用哪个版本的Python来运行它?代码前面是否有来自未来导入部门的
?如果将
/
理解为和/或更改为
/
?@John Machin:/在这种情况下意味着整数除法,是Python2.6没有来自未来的东西,我注意到像jj/m(jj)/m这样的代码在相同的地方,但是我担心这种行为的一致性。现在我可以阅读并理解像这样的代码意味着什么jm/jj/j。如果可以的话,我会给这个答案加10分。:)这是一个非常重要的问题。要有一点哲理性,公认的答案确实是对所问问题的正确答案。这一定意味着问题是错的,而且它问的是“避免使用括号”。最近,我不得不仔细阅读一个正在工作但又难以阅读的库,我对Python的express标准及其在日常实践中的使用的差异非常敏感。为什么你认为我在尝试编写代码?如果…怎么办。。。我正在尝试阅读。我的两个比特值:在只涉及
+-*/
运算符的表达式中期望有多余的括号是荒谬的。。。优先性和结合性(隐式)是在学校代数课上教授的,不是吗?被认为是计算机程序员的基本知识,是/否?另一方面,在项目或团队标准中,必须在ops周围使用括号,如bit shift、bit and、bit or等,这些在不同语言中使用频率不高且优先级不同。如果有疑问,则应始终使用括号。OP实际上是在说他不确定什么优先权适用,所以在这种情况下不依赖它们是正确的;运算符优先级不适用。分配给多个目标在语法中明确定义为:将同一对象分配给多个目标。分配错误,请更改示例!Python中唯一从右向左关联的操作符是
**
,如
2**3**4
@Amber:(1)正如@Nas Banov所说,
**
是唯一一个与自身右关联的Python操作符
>>> m = 1e306
>>> m
1e+306
>>> j = 1e307
>>> j
9.9999999999999999e+306
>>> j / m
10.0
>>> j*j
inf
>>> j * (j / m)
1e+308
>>> (j * j) / m
inf
>>> ((j * j) / m) == (j * (j/m))
False