解包是按位置将可迭代对象的元素依次绑定到左侧变量名的过程,要求对象可迭代且长度匹配;支持list/tuple/str等,带*可收集剩余元素为列表,字典需用.values()等显式提取值。

什么是解包?不是“拆列表”,而是“按位置绑定变量”
解包的本质是把一个可迭代对象的元素,按顺序一一赋值给左侧的变量名。它不关心对象是不是列表,只关心它是否支持迭代、且长度匹配。比如 a, b = [1, 2] 成功,是因为 [1, 2] 有 2 个元素,刚好对应两个变量;而 a, b = [1] 会报 ValueError: not enough values to unpack。
序列解包:list/tuple/str 都行,但长度必须严格匹配
只要对象实现了 __iter__ 且能生成确定数量的项,就能参与基础解包。常见陷阱是误以为只有 tuple 才能解包——其实 a, b = "xy" 合法,a, b = range(2) 也合法。
-
a, b, c = (1, 2, 3)✅ 标准 tuple 解包 -
a, b = [10, 20]✅ list 同样适用 -
a, b = "hi"✅ str 按字符迭代 -
a, b = {1, 2}⚠️ 可能成功,但顺序不保证(set 无序) -
a, b = [1, 2, 3]❌ 报错:too many values to unpack
带 * 的解包:处理不定长场景的核心机制
* 不是“解包剩余元素”,而是“收集剩余位置的所有值为一个列表”。它只能出现在左侧变量列表中最多一次,且不能在末尾连续跟多个变量(如 a, *b, c, d 合法,a, *b, *c 语法错误)。
-
a, *rest, z = [1, 2, 3, 4]→a=1,rest=[2, 3],z=4 -
*head, tail = "abc"→head=['a', 'b'],tail='c' -
first, *middle, last = [5]→first=5,middle=[],last=5(注意:此时 first 和 last 是同一个元素) - 嵌套解包不支持:
(a, *b), c = [(1, 2, 3), 4]❌ 会报 SyntaxError
字典解包:** 是传参用的,不是变量绑定用的
字典本身不能直接用于变量解包(a, b = {'x': 1, 'y': 2} 解出的是 key,不是 value),真正常用的是函数调用时的 ** 解包,它把字典的 key 当作参数名、value 当作实参传入。
立即学习“Python免费学习笔记(深入)”;
-
def f(x, y): return x + y;f(**{'x': 10, 'y': 20})→ 等价于f(x=10, y=20) -
{**d1, **d2}是合并字典的惯用写法,键冲突时后者覆盖前者 - 想解出字典的 value?得显式写:
v1, v2 = d.values()(前提是知道长度) -
for k, v in d.items():是遍历键值对的标准方式,不是解包语法本身
最容易被忽略的是:解包失败时的错误信息非常具体,但新手常忽略看后半句——比如 not enough values to unpack (expected 3, got 2),括号里已经告诉你期望几个、实际几个。另外,* 收集的结果永远是 list,哪怕只剩一个或零个元素。











