Python进阶4——元组与拆包

元组不仅不可变,而且可以通过拆包(取出元组的某些元素)来显示某些信息

twodimpos=(10,20)
x,y=twodimpos#拆包赋值
print(x,y)
length, width, height=(4,5,6)#拆包取出三个元素
print(length)
somecities=[('beijing', 1), ('shanghai', 2),
('guangzhou',3),('shenzhen',4)]

for city in sorted(somecities):
	print('%s %s' % city)#拆包分别取出两个元素
print(somecities)

for cityname, _ in somecities:#_表示占位符,站位符存储城市编号,拆包取出第一个元素
	print(cityname)

第一行代码就是一个普通的元组,通过拆包分别对x和y赋值,第4行和第5行表示用元组分别初始化三个变量

第6行是一个列表元组,第一个for循环将元组中的元素分别显示出来,第二个for循环用占位符来获取城市的名字

 

Python中可以不使用中间变量来交换两个值,这也是拆包的应用之一

twodimpos=(10,30)
x,y=twodimpos
print(x,y)
x,y=y,x
print(x,y)

x,y组合的实质就是一个元组,可以通过交互模式查看

所以可以通过拆包来交换值

 

os.path.split函数接受一个文件所在的路径,返回文件路径和文件组成的元组

可以通过占位符和拆包取出文件名

import os
print(os.path.split('/home/xiaocui/work/fluent-python/tuple.py'))

_, filename=os.path.split('/home/xiaocui/work/fluent-python/tuple.py')
print(filename, _)

占位符一般表示忽略的元素,但是本质依然是个变量,可以正常使用和打印

 

还可以将元组作为参数传入函数,用*将元组拆开,因此也实现了通过*将任意数量的参数传入一个函数中

print(divmod(20,8))
#divmod函数接收两个数字,返回一个元组,元组的第一个元素是商,第二个元素是余数

para=(20,8)
print(divmod(*para))#传入一个元组,并通过*拆包,如果定义的参数数量更多,也可以传入更多的参数,因为*可以将任意数量的参数传入一个函数中
m,n=divmod(*para)
print(m,n)

结果显示,上述两种形式的代码的结果完全相同

 

通过*不仅可以将任意数量的参数传入一个函数中,也可以通过*来进行平行赋值

a,b,c,*other=range(10)
print(a,b,c,other)

a,b,c,*other,d,e,f=range(10)
print(a,b,c,other,d,e,f)

a,b,c,*other=range(3)
print(a,b,c,other)

上述例子表明,*前缀可以出现在中间 变量前面,如果*修饰的变量没有被赋值,则该变量是一个空列表

a,b,c,other的组合其实也是一个元组,和x,y的组合一样

 

嵌套元组的拆包

嵌套元组就是元组中的元素还是元组,即使这样,Python依旧能准确拆包

manpos=[('tom', (10,20)), ('jerry', (10,50))]
for name, (x,y) in manpos:
	print(name, x, y)
	if (y>30):
		print(name, x, y)

上述代码将Tom和Jerry的具体元组座标用一个元组接收,从而实现了在将列表中的元组元素中的元组进行拆包

 

具名元组(namedtuple)

具名元组在collection包中,其中的namedtuple用来构建元组和类

代码示例:

from collections import namedtuple#导入namedtuple
manpostuple=namedtuple('manpostuple', 'name pos')#创建了一个叫manpostuple的类,在使用该类生成对象时,必须传入name参数和pos参数,相当于manpostuple的__init__函数是这样的:def __init__(self, name, pos):
tom1=manpostuple('tom1', (10,20))#创建两个对象,并传入一个字符串和一个元组
jerry1=manpostuple('jerry1', (10,50))
print(tom1, jerry1)#打印出两个带名字的元组,元组的名字是manpostuple,两个元素分别是name和pos
print(tom1.name,tom1.pos, tom1[0], tom1[1])#因为tom既是类的对象,也是元组,所以可以用点访问,也能用下标访问

通过上述代码可知,具名元组(namedtuple)创建的是一个带有名字的元组,同时也是一个类,类名是namedtuple的第一个参数,类的成员变量是namedtuple的第二个参数

 

具名元组的一些属性和函数

继续以上述代码为例,执行如下操作

print(manpostuple._fields)#_fields属性将具名元组manpostuple的参数打包成员组,这里将属性name和pos打包成元组
dog1=('dog1',(10,30))
print(manpostuple(*dog1))#将dog1通过*拆包,传入具名元组manpostuple
print(manpostuple._make(dog1))#等效第三行,所以_make函数的作用就是将dog1拆包,然后生成一个manpostuple对象
print(manpostuple._make(dog1)._asdict())#将manpostuple对象dog1转换为OrderedDict对象
for key, val in manpostuple._make(dog1)._asdict().items():#打印字典中的key value
	print(key, val)

 

参考:

《流畅的Python》

 

欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章