元组
有很多人会将元组看作不可变的列表,这完全忽略了元组的巨大作用。
元组是对数据的记录,正是因为它不可变的特性,让它成为记录数据的强大工具。一个元组对应着一条数据,一条数据包含多个元素。我们通过元素独一无二的位置来获取我们需要的信息。
1. 元组拆包
- 平行赋值
person = ('fancy', 18, 'cute')
name, age, dis = person # 拆包赋值
print(name, age, dis)
person = ['fancy', 18, 'cute'] # 对于其他可迭代对象同样适用
name, age, dis = person
print(name, age, dis).
# 实际上为绑定变量地址到元组相应元素地址上
# 但是改变变量内容,不会影响元组(变量地址改变)
- %适配
person = ('fancy', 18, 'cute')
print('%s %d %s' % person) # %拆包
- *适配
print(divmod(20, 3))
num = (20, 3)
print(divmod(*num)) # *拆包
num = [20, 3]
print(divmod(*num)) # 对于其他可迭代序列同样适用
- 不使用中间变量互换
name1 = 'fancy'
name2 = 'sixday'
name1, name2 = name2, name1 # 互换值
print(name1, name2)
# 交换地址
# 同样适用于序列
- 处理不需要的元素
person = ('fancy', 18, 'cute')
name, _, dis = person # 占位符 _
用*处理剩下的元素
python中,用*args处理剩下的元素是很常见的做法。
tup = ('fancy', 2018, 7 , 30, 'cute')
name, *date, dis = tup
print(date)
>>>[2018, 7, 30]
2. 嵌套元组拆包
tup = ('fancy', (2018,7,30), 'cute')
a, (y,m,d), c = tup
print(y,m,d)
>>>2018 7 30
3. 具名元组
元组作为数据的记录,只能通过下标来获取数据,而不能通过字段名来获取对应数据,是不是很难受呢?具名元组为我们解决了这一问题。
实际上,具名元组是 有字段名 的元组,只是它会生成一个只有属性没有方法的新类型,有些像C语言中结构体的定义。
具名元组类的实例所消耗的内存,与元组是一样的,因为字段名都被存在对应的类里。并且不会以__dict__
存放类的属性,因此与一般的类实例相比,占内存也会小很多。
- 库:
collections.namedtuple
- 函数原型:
namedtuple(typename, field_names[, verbose=False][, rename=False])
- 返回类型:定义的新类型
- typename:类名,string类型
- field_names: 字段名,可以是由空格分开的字符串,也可以是由字符串组成的可迭代序列
- verbose:vervose=True,创建类之前在输出台打印类的定义
- rename:rename=True,对field_names中无效的字段进行替换,根据位置进行替换。
Cls = collections.namedtuple('Cls', 'name tel age')
fancy = Cls('fancy', '1111', 8)
print(fancy.name) # 通过标签访问
print(fancy[1]) # 通过下标访问
Cls = collections.namedtuple(
'Cls', ['def', 'cute', '123'],
verbose=True, rename=True)
['_0', 'cute', '_1'] # 被替换之后的字段名
除去从tuple继承而来的属性之外,namedtuple还有自己的几个特殊属性。
- 类属性_fields
# 类属性_fields 给出所有字段名
Cls = collections.namedtuple('Cls', 'name tel age')
fancy = Cls('fancy', '1111', 8)
print(Cls._fields)
print(fancy._fields)
>>>('name', 'tel', 'age')
>>>('name', 'tel', 'age')
- 类方法_make(iterable)
# 类方法_make(iterable) 用一个可迭代对象构造类的实例
# 原本是以传多个参数来构造的,也可以同元组一样传可迭代对象构造
Cls = collections.namedtuple('Cls', 'name tel age')
fancy = ('fancy', '1111', 8)
obj = Cls._make(fancy) # 相当于 obj = Cls(*fancy)