【问题标题】:Iterable Unpacking Evaluation Order [duplicate]可迭代的拆包评估顺序 [重复]
【发布时间】:2018-05-30 06:06:43
【问题描述】:

我最近回答了a question,用户遇到了麻烦,因为他们将多维数组附加到另​​一个数组,我在回答中注意到可以使用可迭代解包来填充 @ 987654322@ 和 y 值并分配给同一行上的 board[x][y]

我曾预计这会引发错误,因为 xy 当时尚未定义,因为即使在 iterable-unpacking 标记中也是如此:

可迭代的元素同时分配给多个值

这可以看作是在以下示例中起作用:

>>> board = [[0, 0], [0, 0]]
>>> move = [0, 1, 2]
>>> x, y, board[x][y] = move
>>> board
[[0, 2], [0, 0]]

等同于:

>>> board = [[0, 0], [0, 0]]
>>> move = [0, 1, 2]
>>> x = move[0]
>>> y = move[1]
>>> board[x][y] = move[2]
>>> board
[[0, 2], [0, 0]]

然而,当使用以下方法计算斐波那契数列时:

a, b = b, a + b

它不评估为:

a = b
b = a + b

当交换值时:

a, b = b, a

它不评估为:

a = b
b = a

那么为什么这在第一个示例中有效?

【问题讨论】:

  • 这些例子似乎并不相同。我的意思是,在第一个例子中,你有<some variables> = <some constant values>。第二个示例尝试在= 的两侧涉及相同的变量。
  • 我认为在标题中使用“异步”有点偏离问题的主题,可能会导致人们在错误的方向上搜索 python async。也许更像是“可迭代的拆包评估顺序”?
  • @Aaron 谢谢,我想不出更好的术语,所以我只是在谷歌上搜索了同步的反义词,我现在就改变它

标签: python variable-assignment iterable-unpacking


【解决方案1】:

= 的右侧总是首先被评估,在这种情况下它正在打包一个元组。然后在解释左侧时对该元组进行解包。左右两边不共享变量知识。 RHS 成为一个值,然后 LHS 使用该 分配给变量(标签)。

在您的示例中,xy 的值是在评估 RHS 后确定的。然后从左到右进行解包,因此board[x][y] 具有有效的索引。

切换顺序演示拆包顺序:

>>> board[x][y], x, y = move[2], move[0], move[1]
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-7-a984ef3168f8> in <module>()
----> 1 board[x][y], x, y = move[2], move[0], move[1]    
NameError: name 'x' is not defined

【讨论】:

  • 虽然我发现它不太可能改变,但这是在任何地方说明的预期行为,还是只是一个实现细节?我可以看到自动并行化可能会破坏这一点的潜在未来情况(同样,不太可能但可能)。
  • docs.python.org/3.6/reference/… "虽然赋值的定义暗示左手边和右手边的重叠是‘同时’的(例如a, b = b, a交换两个变量) , 赋值变量集合中的重叠从左到右发生, 有时会导致混淆. 例如, 下面的程序打印 [0, 2]: x = [0, 1] i = 0 i, x[i ] = 1, 2 # i 更新,然后 x[i] 更新 print(x)
猜你喜欢
  • 1970-01-01
  • 2012-02-03
  • 1970-01-01
  • 1970-01-01
  • 2019-01-15
  • 2015-04-07
  • 2013-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多