【问题标题】:Order of calculation计算顺序
【发布时间】:2020-02-12 06:02:44
【问题描述】:

示例:10 ** 4*3 ** 2

我们老师说python先计算3**2再计算10**4再乘以答案。

但是如果乘法两边的优先级相同,python从左到右读取,不是先10**43**2吗?

(我的问题不是关于操作的顺序或优先级,因为双方的优先级相同)

【问题讨论】:

  • @gst 真的不像是复制品
  • 不是重复的。上面的链接问题与求幂的结合性有关。 OP是正确的,老师是错误的,尽管对于相等优先级的纯粹计算,顺序实际上并不重要。
  • @prashantrana 不,链接的问题仅与求幂及其关联性有关。这是关于两个不同操作之间的优先级。
  • @gst 一是跟联想无关,二是老师的说法有误,所以不能重复。

标签: python


【解决方案1】:

你的老师错了。来自https://docs.python.org/3/reference/expressions.html#evaluation-order

6.15。评估顺序

Python 从左到右计算表达式。请注意,虽然 评估分配,右侧在评估之前评估 左侧。

* 有两个表达式作为其操作数,10**43**2。首先计算左操作数10**4,然后计算右操作数3**2

您的老师可能会与2 ** 3 ** 4 之类的求幂 混淆。这里的“外部”取幂有两个参数23 ** 4(而不是2**34,因为右关联性)。但是,2 仍会在 3**4 之前进行评估。

对于这样一个简单的表达式,它并不重要。但是,如果一个或两个操作数都涉及具有副作用的函数调用,这可能很重要。考虑像@​​987654334@ 这样的人为设计。无论哪种方式,表达式的值都是 7,但调用 print 函数的顺序会影响输出。但是,Python 保证 3 将在 4 之前输出。


某些语言(尤其是 C、IIRC)没有指定评估顺序,因此首先评估左侧还是右侧是一个实现细节。这意味着您无法预测 i=3; j=(i++)*i 之类的值; j 可以是3*3 == 94*3 == 12,这取决于i 在计算右侧操作数之前还是之后递增。 (不过,我不记得这是否被认为是未定义的行为或实现定义的行为。)

【讨论】:

  • 很好的答案。谢谢
【解决方案2】:

我们可以很容易地测试它:

class C:
    def __init__(self, v): 
        self.v = v 

    def __pow__(self, x): 
        print(f'eval {self.v} ** {x}') 
        return self.v ** x 

>>> C(1) ** 2 * C(4) ** 5
eval 1 ** 2
eval 4 ** 5
1024

简而言之,你的老师错了,至少对于 Python 3.7 来说是这样。无论如何,无论它是否属实,我都不会依赖这里的顺序,因为这些假设会降低代码的可读性。

【讨论】:

  • 该死,我打字的时候你打我:-)
  • 这可能只是揭示了(我假设)CPython 的实现细节。我不记得语言本身是否指定从左到右评估运算符的参数。 (如果有选择的情况下,如果操作员费心从右到左评估它们,我会非常感到惊讶。)
  • @chepner 语言也没有规定从右到左,这个反例证明至少声称从右到左是错误的。
  • 讨论点:我发现 Python 的参考明确指定了从左到右的评估。
猜你喜欢
  • 1970-01-01
  • 2014-01-30
  • 1970-01-01
  • 2023-01-11
  • 2011-01-14
  • 1970-01-01
  • 2014-08-03
  • 2016-05-24
  • 2023-03-17
相关资源
最近更新 更多