【问题标题】:Tricky order of evaluation in multiple assignment多重分配中的棘手评估顺序
【发布时间】:2016-02-23 11:13:24
【问题描述】:

我知道 Python 中多重赋值的基本规则:

  • 首先计算赋值右侧的所有表达式
  • 然后评估值绑定到左侧的变量

但实际上我遇到了一些完全不同且更复杂的事情;我想知道我是否可以依赖它。在调试一个算法的时候,突然发现一个bug和这行有关:

k[s], k[p] = k[p], None

因为我的算法发现了sp 相等的情况。显然在这种情况下,最终值是k[s]=k[p]=None

在那种非常具体的情况下,我更希望得到以下结果:

k[p], k[s] = None, k[p]

即使在p == s 时,它在所有情况下都按照我的意愿行事。在这种情况下,显然k[p] 最初取值None,然后取回值k[p]

当然,我知道为了获得更易读的代码而多做一次测试可能是个好主意,但我很想知道在那个鲜为人知的情况下语言的政策:当同一个变量在多次赋值中受到两次影响时会发生什么?

【问题讨论】:

    标签: python variables operator-precedence


    【解决方案1】:

    是的,你应该可以依赖这个。

    来自reference documentation

    如果目标列表是逗号分隔的目标列表:该对象必须是与目标列表中的目标具有相同数量的项目的可迭代对象,并且从左到右分配项目,到相应的目标。

    (强调我的)

    k[s], k[s] = k[s], None
    

    等价于

    t = k[s]
    k[s] = t
    k[s] = None
    

    旁注:当右侧是动态可迭代时,评估顺序也成立,例如一个发电机。将首先提取所有必要的元素并从左到右分配。

    【讨论】:

    • 当然,虽然您可以依赖它,但您不应该,因为显式顺序赋值使代码在排序时更加清晰的任务事项。我可能会将k[p], k[s] = None, k[p] 包裹在if p != s 中以获得最大清晰度。
    • @user2357112 或者至少写一个注释为什么代码在极端情况下也能按预期工作。仍然是“Djikstra would not have liked this”。
    【解决方案2】:

    pythondocs给出了答案:

    如果目标列表是逗号分隔的目标列表:该对象必须是与目标列表中的目标具有相同数量的项目的可迭代对象,并且将项目分配给from left to right对应的目标。

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 1970-01-01
      • 2017-08-20
      • 2012-02-02
      • 2014-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-03
      相关资源
      最近更新 更多