多重赋值语义

70 投票
5 回答
36252 浏览
提问于 2025-04-16 12:56

在Python中,你可以这样做:

a, b   = 1, 2
(a, b) = 1, 2
[a, b] = 1, 2

我用dis检查了生成的字节码,它们是一样的。
那么为什么要允许这样做呢?我会不会需要其中一个而不是另一个?


另外,关于这种赋值的基本语义,可以查看 多个赋值和评估顺序在Python中的应用

还有,关于更复杂的情况,赋值顺序很重要,可以参考 理解Python的交换:为什么 a, b = b, a 不总是等同于 b, a = a, b?

5 个回答

4

当我们要把一个只有一个元素的可迭代对象拆开时,用列表的写法看起来更好看:

a,=f()    # comma looks out of place
(a,)=f()  # still odd
[a]=f()   # looks like every other list
13

在Python中,元组(tuple)有时候可以写成有括号的样子,也可以不加括号:

a = 1, 2, 3

这两种写法是等价的

a = (1, 2, 3)

不过在某些情况下,为了避免混淆,你需要用括号。比如,如果你想把元组 (1, 2) 传给函数 f,你就得写成 f((1, 2))。因为有时候需要括号,所以为了保持一致性,你总是可以使用括号,就像你可以写 (a + b) 代替 a + b 一样。

如果你想要拆解一个嵌套的序列,你也需要用括号:

a, (b, c) = 1, (2, 3)

看起来没有必要使用方括号,实际上人们也很少这么做。

75

有一种情况是,当你需要在赋值的左边加更多的结构时,就是你想让Python处理一个稍微复杂一点的序列。例如:

# Works
>>> a, (b, c) = [1, [2, 3]]

# Does not work
>>> a, b, c = [1, [2, 3]]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: need more than 2 values to unpack

我过去发现这很有用,比如在使用enumerate来遍历一系列的二元组时。像这样:

>>> d = { 'a': 'x', 'b': 'y', 'c': 'z' }
>>> for i, (key, value) in enumerate(d.iteritems()):
...     print (i, key, value)
(0, 'a', 'x')
(1, 'c', 'z')
(2, 'b', 'y')

撰写回答