【问题标题】:The mechanism behind multiple assignment in PythonPython中多重赋值背后的机制
【发布时间】:2021-07-02 13:03:32
【问题描述】:

我们都知道多重赋值可以一次赋值多个变量,这在swap中很有用。 在这种情况下效果很好:

nums = [2, 0, 1]
nums[0], nums[2] = nums[2], nums[0]
# nums=[1, 0, 2] directly, correct

,但在更复杂的情况下失败了,例如:

nums = [2, 0, 1]
nums[0], nums[nums[0]] = nums[nums[0]], nums[0]
# nums=[1, 2, 1] directly, incorrect

nums = [2, 0, 1]
tmp = nums[0]
nums[0], nums[tmp] = nums[tmp], nums[0]
# nums=[1, 0, 2] with temporary variable, correct

似乎在nums[nums[0]]nums[0] 将被分配之前,而不是一次。 在复杂的链表节点交换中也失败了,例如:

cur.next, cur.next.next.next, cur.next.next = cur.next.next, cur.next, cur.next.next.next
# directly, incorrect

pre = cur.next
post = cur.next.next
cur.next, post.next, pre.next = post, pre, post.next
# with temporary variable, correct

所以我想知道Python中多重赋值背后的机制,什么是最佳实践,临时变量是唯一的方法?

【问题讨论】:

  • 这是评估顺序的问题。两侧订阅相同数组的赋值中的求值顺序没有明显的顺序。这样c, b = b, ca = b, c; c, b = a 不同。我希望我能记住还有哪个问题涵盖了这一点。

标签: python


【解决方案1】:
a, b = c, d

等价于

temp = (c, d)
a = temp[0]  # Expression a is evaluated here, not earlier
b = temp[1]  # Expression b is evaluated here, not earlier

我个人建议像您展示的那样使用临时变量显式编写复杂的赋值。

另一种方法是仔细选择赋值中元素的顺序:

nums[nums[0]], nums[0] = nums[0], nums[nums[0]]

如您所愿更改nums

【讨论】:

  • 那个等价是假的。 a, b = c, d 不等于 e = c, d; a, b = e
  • @DanD。反例?
  • 问题中的代码是这样的。如果两者是等价的,这个问题就不会被问到。
  • @DanD。 temp = nums[nums[0]], nums[0]; nums[0], nums[nums[0]] = temp 产生与问题中的nums[0], nums[nums[0]] = nums[nums[0]], nums[0] 相同的结果。
  • 是的,我想我同意@MichaelButscher,右手边打包到一个元组,左手的分配顺序导致问题,参考quora.com/How-does-multiple-assignment-work-in-Python
猜你喜欢
  • 1970-01-01
  • 2021-03-30
  • 2019-02-27
  • 1970-01-01
  • 2018-03-04
  • 2023-03-04
  • 2018-08-13
  • 2014-04-12
相关资源
最近更新 更多