元组拆包
元组一般被当作不可变的列表,但元组的元素还携带着位置信息,所以就有了元组拆包的用法。
>>> lax_coordinates = (33.9425, -118.408056) # 1
>>> city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014) # 2
>>> traveler_ids = [('USA', '31195855'), ('BRA', 'CE342567')]
>>> for passport in sorted(traveler_ids):
... print('%s/%s' % passport) # 3
...
BRA/CE342567
USA/31195855
>>> for country, _ in traveler_ids: # 4
... print(country)
...
USA
BRA
(1)定义元组用的是圆括号。
(2)元组拆包的用法,赋值表达式左边每个变量的位置对应右边的字面量,然后做赋值操作。
(3)passport是一个元组,%格式运算符能够匹配对应的元组元素。
(4)_ 作为一个占位符,对我们没用的值赋给它。
元组拆包可以应用到任何可迭代对象上,唯一要求是接受元素的元组必须能匹配上的变量,所以元组拆包也可以称作可迭代元素拆包。
>>> a, b = (1,2)
>>> a
1
>>> (c,d) = (3,4) # 1
>>> c
3
>>> e,f = [5,6] # 2
>>> e
5
>>> a, b = b, a # 3
>>> a
2
(1)表达式左边的变量列表有无括号都可以接受元素。
(2)可迭代元素拆包的用法跟元组拆包一样。
(3)不用临时变量交换两个变量的值。
* 运算符
*运算符也可以拆开可迭代元素,或者用来获取不确定数量的参数。
>>> divmod(20,8)
(2, 4)
>>> t=(20,8)
>>> divmod(*t) # 1
(2, 4)
>>> a,b = divmod(*t) # 2
>>> a
2
(1)*t 对 t 元组进行拆包,元素一一对应函数的参数并传入。
(2)函数返回元组也可以平行地接受。
*运算符接一个变量用来获取不确定数量的参数,0个或0个以上,不限定位置。
>>> a,b,*rest = range(5)
>>> a,b,*rest
(0, 1, 2, 3, 4)
>>> a,b,rest
(0, 1, [2, 3, 4])
>>> a,b,*rest = range(3)
>>> a,b,rest
(0, 1, [2])
>>> a,b,*rest = range(2)
>>> a,b,rest
(0, 1, [])
>>> a,*rest,b = range(5)
>>> a,rest,b
(0, [1, 2, 3], 4)
嵌套元组拆包
嵌套元组拆包跟一般的元组拆包没差别,只要结构对应上跟接受元素的变量。
>>> a,(b,c,d),e = (0,(1,2,3),4)
>>> a,b,c,d,e
(0, 1, 2, 3, 4)
具名元组
具名元组是给元组的元素带上字段名,用 collection.namedtuple 实现,这是一个工厂函数,构造出一个类名和带一个字段名的元组。
namedtuple构造的类的实例所消耗的内存跟元组是一样的,因为字段名都被存在对应的类里面。
定义和使用具名元组:
>>> from collections import namedtuple
>>> City = namedtuple('City', 'name country population coordinates') # 1
>>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139,691667)) # 2
>>> tokyo
City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139, 691667))
>>> tokyo.population
36.933
>>> tokyo.coordinates
(35.689722, 139, 691667)
>>> tokyo[1]
'JP'
(1)构造可以创建具名元组的类,参数一是类名,参数二是字段名的列表。
(2)给(1)得到的构造函数传入各个字段的参数,以构造具名元组。
(3)访问具名元组的元组可以用下标或字段名。
具名元组还提供了自己独有的属性,例如 _fields类属性、类方法 _make(iterable) 和实例方法 _asdict()。
>>> City._fields # 1
('name', 'country', 'population', 'coordinates')
>>> delhi_data = ('apple', 'in', 21.939, (28.613889, 77.208889))
>>> delhi = City._make(delhi_data) # 2
>>> delhi._asdict() # 3
{'name': 'apple', 'country': 'in', 'population': 21.939, 'coordinates': (28.613889, 77.208889)}
(1)_fields类属性返回所有的字段名。
(2)_make类方法接收参数创建具名元组。
(3)_asdict实例方法,返回字段名和对应的值。
不可变的列表
元组的元素不可变,但元素是一个引用的话,那么元素引用的值可变。
>>> a = 123
>>> b = [1,2]
>>> t = (a, '2', b) # 1
>>> t[2]
[1, 2]
>>> t[2][0]
1
>>> t[2][0] = 3 # 2
>>> t[2]
[3, 2]
(1)b是一个列表,元素可变。
(2)修改 b 列表的元素,可以发现修改成功。