3.1 元组拆包
拆包可以应用到任何可迭代对象上(str、list等),唯一的硬性要求是,被可迭代对象中的元素数量必须要跟接受这些元素的元组的空档数一致。除非我们用
*
来表示忽略多余的元素
平行赋值拆包:
完全拆包,左侧变量必须和元组元素数量一致;
# 平行赋值
city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014)
print(city, year, pop, chg, area) # Tokyo 2003 32450 0.66 8014
用 _ 占位不需要的元素:
# 用 _ 占位不需要的元素
city, _, _ = ('Tokyo', 2003, 32450)
print(city) # Tokyo
用 *vars 处理多余的元素:
# 用 * 处理多余的元素
city, year, *other = ('Tokyo', 2003, 32450, 0.66, 8014)
print(city, year, other) # Tokyo 2003 [32450, 0.66, 8014]
用 * 拆包元组作为函数的参数:
# 用 * 拆包元组作为函数的参数
t = (3, 4)
dt = divmod(*t) # divmod() 计算两个数值,返回商和余数
print(dt) # (0, 3)
3.2 嵌套元组拆包
接受表达式的元组可以是嵌套式的,例如
(a, b, (c, d))
。只要这个接受元组的嵌套结构符合表达式本身的嵌套结构,Python 就可以作出正确的对应。
# 嵌套元组拆包
metro_areas = [
('Tokyo', 'JP', 36, (35, 139)),
('Delhi NCR', 'IN', 21, (28, 77)),
('Sao Paulo', 'BR', 19, (-23, -46)),
]
# metro_areas 的元素是嵌套元组
for city, country, pop, (lat, long) in metro_areas:
print(city, country, pop, lat, long)
# Tokyo JP 36 35 139
# Delhi NCR IN 21 28 77
# Sao Paulo BR 19 -23 -46
3.3 具名元组
collections.namedtuple
是一个工厂函数,它可以用来构建一个带字段名的元组和一个有名字的类——这个带名字的类对调试程序有很大帮助。
import collections
# 创建一个具名元组需要两个参数,一个是类名,另一个是类的各个字段的名字。
# 后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串。
Point = collections.namedtuple('Points', ['x', 'y'])
print(Point.__doc__, type(Point)) # Points(x, y) <class 'type'>
# 返回字段名
print(Point._fields) # # ('x', 'y')
# 接受一个可迭代对象作为字段,创建一个新的类实例
c = (1, 2)
j = Point._make(c)
# 用位置参数或关键字实例化
p = Point(11, y=22)
a = p[0] + p[1] # 可以像普通元组一样索引取值
print(a) # 33
# 可以像普通元组一样拆包
x, y = p
print(x, y) # 11 22
# 可以像对象一样访问属性
print(p.x, p.y) # 11 22
# 可以转成字典格式(collections.OrderedDict 类型,不是真正的字典)
d = p._asdict()
print(d['x'], d.get('x')) # 11
# 字典拆包传值
Point(**d) # Point(x=11, y=22)
# 替换目标的值
p._replace(x=100) # _replace() is like str.replace() but targets named fields
# Point(x=100, y=22)
3.3 作为不可变列表的元组
如果要把元组当作列表来用的话,最好先了解一下它们的相似度如何。在表 2-1 中可以清楚地看到,除了跟增减元素相关的方法之外,元组支持列表的其他所有方法。还有一个例外,元组没有 __reversed__
方法,但是这个方法只是个优化而已,reversed(my_tuple)
这个用法在没有 __reversed__
的情况下也是合法的。
表2-1:列表或元组的方法和属性(那些由object
类支持的方法没有列出来)
| 列表 | 元组 |
|
---|---|---|---|
| • | • |
|
| • |
|
|
| • |
| 在尾部添加一个新元素 |
| • |
| 删除所有元素 |
| • | • |
|
| • |
| 列表的浅复制 |
| • | • |
|
| • |
| 把位于 |
| • |
| 把可迭代对象 |
| • | • |
|
|
| • | 在 |
| • | • | 在 |
| • |
| 在位置 |
| • | • | 获取 |
| • | • |
|
| • | • |
|
| • |
|
|
| • | • |
|
| • |
| 删除最后或者是(可选的)位于 |
| • |
| 删除 |
| • |
| 就地把 |
| • |
| 返回 |
| • |
|
|
| • |
| 就地对 |