在上一节Python数据结构——序列构成的数据之内置序列 中有提到元组,元组除了用作不可变的列表,它还可以用于没有字段名的记录。本文就来好好学习一下元组这种数据结构。
元组和记录
元组其实是对数据的记录:元组中的每个元素都存放了记录中的一个字段的数据,外加这个字段的位置。正是这个位置信息给数据赋予了意义。
lax_coordinates = (33.9435, -118.408056)
# 一个元组列表,元组的形式为(country_code,passport_number)
traveler_ids = [('USA', '31195855'), ('BRA', 'CE342567'), ('ESP', 'XDA345533')]
# 在迭代的过程中,passport变量被绑定到每个元组上
for passport in sorted(traveler_ids):
print('%s--%s' % passport) #%运算符能被匹配到对应的元组元素上
for country, _ in traveler_ids:#"_"为占位符
print(country)
结果如下:
BRA--CE342567
ESP--XDA345533
USA--31195855
USA
BRA
ESP
如果把元组当作一些字段的集合,那么数量和位置信息就变得非常重要了。
元组拆包
Python 爱好者们很喜欢元组拆包这个说法,但是可迭代拆包这个表达也慢慢流行了起来。
# 最好辨认的元组拆包形式就是平行赋值
lattitude, longitude = lax_coordinates
print(lattitude, longitude)
# 不适用中间变量交换两个变量的值,利用元组拆包实现
a, b = 1, 2
b, a = a, b
print(a, b)
# 用*运算符把一个可迭代对象拆开作为函数的参数
print(divmod(20, 8))
t = (20, 8)
print(divmod(*t))
quotient, remainder = divmod(*t)
print(quotient, remainder)
# 嵌套元组拆包
numbers = [
('a', 1, (11, 111)),
('b', 2, (22, 222)),
('c', 3, (33, 333))
]
for a, b, (c, d) in numbers:
print(c,d)
结果如下:
33.9435 -118.408056
2 1
(2, 4)
(2, 4)
2 4
11 111
22 222
33 333
具名元组
collections.namedtuple 是具有命名字段的元组的工厂函数。具名元组为元组中的每个位置赋予含义,并允许更可读,自我记录的代码。它们可以在使用常规元组的任何地方使用,并且它们添加了按名称而不是位置索引访问字段的功能。
创建一个具名元组需要两个参数,一个是类名,另一个是类的各字段的名字。后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串。
在我的上篇文章用 Python 打扑克牌——炸金花中有详细的使用。
from collections import namedtuple
City = namedtuple('City','id name')
# City = namedtuple('City',[id,name])
c1 = City(1,'beijing')
print(c1.id,c1.name)
print(City._fields)#返回这个类所有字段名称的元组
t = (2,'shanghai')
c2 = City._make(t)#用_make()接收一个可迭代对象来生成这个类的一个实例,与City(*t)效果一样
# c2 = City(*t)
print(c2)
结果如下:
1 beijing
('id', 'name')
City(id=2, name='shanghai')
作为不可变列表的元组
元组是另一个数据类型,类似于 List(列表)。元组用 () 标识。内部元素用逗号隔开。但是元组不能二次赋值,相当于只读列表。
本文作者为hresh,转载请注明。