序列解包
序列解包(Sequence Unpacking)是 Python 中一种简洁的赋值语法,把序列中的元素一次性赋给多个变量。它让代码更紧凑、更 Pythonic。
基本解包
# 元组解包
point = (3, 4)
x, y = point
print x # 3
print y # 4
# 列表解包
coords = [10, 20, 30]
x, y, z = coords
print x, y, z # 10 20 30
# 字符串解包
a, b, c = "abc"
print a, b, c # a b c
解包时,变量数必须与序列元素数完全匹配:
t = (1, 2, 3)
a, b = t # ValueError: too many values to unpack
a, b, c, d = t # ValueError: need more than 3 values to unpack
交换变量
解包最经典的用途是交换两个变量,无需临时变量:
a, b = 10, 20
a, b = b, a
print a, b # 20 10
原理:右边 b, a 先打包成元组 (20, 10),然后解包给左边的 a, b。
函数返回多个值
函数可以返回元组,调用时直接解包:
def get_min_max(nums):
return min(nums), max(nums)
minimum, maximum = get_min_max([3, 1, 4, 1, 5])
print minimum, maximum # 1 5
实际上函数只返回一个对象——元组。解包语法让调用方感觉像是返回了多个值。
遍历键值对
解包与字典遍历结合,是最常见的用法:
d = {"a": 1, "b": 2, "c": 3}
for key, value in d.iteritems():
print key, value
# 等价于:
for item in d.iteritems():
key, value = item
print key, value
enumerate 解包
enumerate() 返回 (index, value) 元组,天然适合解包:
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
print index, fruit
# 输出:
# 0 apple
# 1 banana
# 2 cherry
# 指定起始索引
for index, fruit in enumerate(fruits, 1):
print index, fruit
# 输出:
# 1 apple
# 2 banana
# 3 cherry
zip 解包
zip() 并行遍历多个序列,返回元组序列:
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
print name, age
# 输出:
# Alice 25
# Bob 30
# Charlie 35
zip 以最短序列为准:
a = [1, 2, 3]
b = ["a", "b"]
for x, y in zip(a, b):
print x, y
# 输出:
# 1 a
# 2 b
用 _ 忽略不需要的值
如果某些值不需要,可以用 _ 作为占位符(约定俗成):
# 只关心文件名和大小,忽略修改时间
filename, _, size = ("data.txt", "2024-01-01", 1024)
print filename, size # data.txt 1024
# 遍历时忽略索引
for _, value in enumerate(items):
process(value)
嵌套解包
元组中的元组也可以直接解包:
points = [(1, 2), (3, 4), (5, 6)]
for x, y in points:
print x, y
# 输出:
# 1 2
# 3 4
# 5 6
解包的限制
Python 2 不支持扩展解包(*rest),这是 Python 3 的特性。在 Python 2 中需要切片:
# Python 3:first, *rest = [1, 2, 3, 4, 5]
# Python 2:
nums = [1, 2, 3, 4, 5]
first = nums[0]
rest = nums[1:]
# Python 3:first, *middle, last = nums
# Python 2:
first = nums[0]
last = nums[-1]
middle = nums[1:-1]