《流畅的python》读书笔记(4)

2.3 元组不仅仅是不可变的列表

除了用作不可变的列表,元组还可以用于没有字段名的记录。

元组其实是对数据的记录:元组中的每个元素都存放了记录中一个字段的数据,外加这个
字段的位置。正是这个位置信息给数据赋予了意义。如果把元组当作一些字段的集合,那么数量和位置信息就
变得非常重要了。

元组用作记录

# 示例2-7 把元组用作记录

	# 洛杉矶国际机场的经纬度。
	lax_coordinates = (33.9425, -118.408056)

	# 东京市的一些信息:市名、年份、人口(单位:百万)、人口变化(单位:百分比)
	# 和面积(单位:平方千米)。将元组中的每一个元素 赋值给一个变量,给予它特定的含义
	# 这就称为元组的拆包
	city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014)

	# 一个元组列表,元组的形式为 (country_code, passport_number)
	traveler_ids = [
		('USA', '31195855'),
		('BRA', 'CE342567'),
		('ESP', 'XDA205856')
	]

	# 在迭代的过程中,passport 变量被绑定到每个元组上
	for passport in sorted(traveler_ids):
		# % 格式运算符能被匹配到对应的元组元素上。
		# 一个 % 运算符就把 passport 元组里的元素对应到了 print 函数
		# 的格式字符串空档中,这也是元组拆包的应用
		print('%s / %s' % passport)

	# for 循环可以分别提取元组里的元素,也叫作拆包(unpacking)。因为元组中第二个
	# 元素对我们没有什么用,所以它赋值给“_”占位符。
	# 拆包让元组可以完美地被当作记录来使用
	for country, _ in traveler_ids:
		print(country)

元组拆包

元组拆包可以应用到任何可迭代对象上,唯一的硬性要求是,被可迭代对象中
的元素数量必须要跟接受这些元素的元组的空档数一致

最好辨认的元组拆包形式就是平行赋值,也就是说把一个可迭代对象里的元素,一并赋
值到由对应的变量组成的元组中。

比如优雅的不使用中间变量交换两个变量的值的方法
b , a = a , b

#元组拆包范例
	lax_coordinates = (33.9425, -118.408056)
	# 平行赋值将元组拆包
	latitude, longitude = lax_coordinates;
	print(latitude)
	# 33.9425
	print(longitude)
	# -118.408056

	# python divmod() 函数把除数和余数运算结果结合起来,
	# 返回一个包含商和余数的元组(a // b, a % b)
	d = divmod(20, 8)
	print(d)
	# (2, 4)

	# 用 * 运算符把一个可迭代对象拆开作为函数的参数:
	t = (20, 8)
	result = divmod(*t)
	print(t)
	# (2, 4)
	quotient, remainder = divmod(*t)
	print(quotient)
	# 2
	print(remainder)
	# 4
	
	
	
	import os

	# os.path.split("/home/shuaibi/niupi/idrsa.pub")该函数返回
	# 以路径和最后一个文件名组成的元组
	# 会打印('/home/shuaibi/niupi', 'idrsa.pub')
	print(os.path.split("/home/shuaibi/niupi/idrsa.pub"))

	# 使用元组拆包则会轻松的只拿到 最后一个文件的文件名
	_, filename = os.path.split("/home/shuaibi/niupi/idrsa.pub")
	# "_"占位符能够处理掉前面的文件路径
	print(_)    # 实际上,这个占位符还是保存着这个路径变量的 /home/shuaibi/niupi
	# /home/shuaibi/niupi
	print(filename)
	# idrsa.pub

	# 在元组拆包中使用*来处理剩下的元素

	a, b , *rest = range(5)
	print(a,b,rest)
	# 0 1 [2, 3, 4]

	a,b,*rest = range(3)
	print(a,b,rest)
	# 0 1 [2]

	a,b,*rest = range(2)
	print(a,b,*rest)
	# 此处和书中的结果并不一样 在pycharm中这样执行 打印0 1  rest并不会显示
	# 在命令行中 执行结果和书中相同
	# >>> a,b,*rest = range(2)
	# >>> a,b,rest
	# (0, 1, [])
	c = []
	print(c)
	# 但是 自定义个空列表的话是可以打印出来的 [] pycharm这个执行的机制
	# 具体是怎么回事,弱鸡的我是真的不知道。希望有朝一日有大佬能够看到
	# 这篇文章 给我指点一下子
	
	# 言归正传
	# 在平行赋值中,* 前缀只能用在一个变量名前面,但是这个变量可以出现在赋值表达式的
	# 任意位置

	a, *body, c, d = range(5)
	print(a, body, c, d)
	# 0 [1, 2] 3 4

	*head, b, c, d = range(5)
	print(head, b, c, d)
	# [0, 1] 2 3 4

具名元组

collections.namedtuple 是一个工厂函数,它可以用来构建一个带字段名的元组和一
个有名字的类——这个带名字的类对调试程序有很大帮助

用 namedtuple 构建的类的实例所消耗的内存跟元组是一样的,因为字段名都
被存在对应的类里面。这个实例跟普通的对象实例比起来也要小一些,因为 Python
不会用 dict 来存放这些实例的属性

# 展示如何使用用具名元组来记录一个城市的信息
	from collections import namedtuple

	# 创建一个具名元组需要两个参数,一个是类名,另一个是类的各个字段的名字。后者
	# 可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串。
	City = namedtuple('City', 'name country population coordinates')

	# 存放在对应字段里的数据要以一串参数的形式传入到构造函数中(注意,元组的构造
	# 函数却只接受单一的可迭代对象)
	#             name  country population   coordinates
	tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))

	print(tokyo)
	# City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))

	# 可以通过字段名或者位置来获取一个字段的信息
	print(tokyo.population)
	# 36.933

	print(tokyo.coordinates)
	# (35.689722, 139.691667)

	print(tokyo[0])
	# Tokyo
	print(tokyo[1])
	# JP

	# _fields 属性是一个包含这个类所有字段名称的元组。
	print(City._fields)
	# ('name', 'country', 'population', 'coordinates')

	# 又创建一个nametuple 稍后初始化为具体对象并当作参数传入
	LatLong = namedtuple("LatLong", "lat long")

	# 创建一个数据集合
	delhi_data = ("Delhi NRC", "IN", 21.935, LatLong(28.613889, 77.208889))

	# 通过数据集合 新建一个城市对象
	# 用 _make() 通过接受一个可迭代对象来生成这个类的一个实例,它的作用跟
	# City(*delhi_data) 是一样的
	delhi = City._make(delhi_data)

	# _asdict() 把具名元组以 collections.OrderedDict 的形式返回,我们可以利用它
	# 来把元组里的信息友好地呈现出来
	delhi_datas = delhi._asdict()
	print(delhi_datas)
	# OrderedDict([('name', 'Delhi NRC'), ('country', 'IN')
	# , ('population', 21.935), ('coordinates', LatLong(lat=28.613889, long=77.208889))])

	for key, value in delhi._asdict().items():
		print(key + ' : ', value)
	# name :  Delhi NRC
	# country :  IN
	# population :  21.935
	# coordinates :  LatLong(lat=28.613889, long=77.208889)

元组不仅可以当作记录用的数据类型,而且也可以充当一个不可变的列表

作为不可变列表的元组

首先 看一下书中的一个元组与列表的对比表
在这里插入图片描述
在这里插入图片描述
除了跟增减元素相关的方法外 元组支持列表的其他所有的方法

小结

掌握拆包的方法,这本书中的很多代码都是比较。。。怎么说 很Python的风格的代码
不带一点方言。。。所以 对于我这种基础不扎实的 需要好好理解。就比如那个format的规则,
平时不经常用,研究了一会才知道怎么运作的。 另外就是自己对于nametuple的使用感受,
可以当作一个C的结构体类似的东西使用,(又带方言了。。)到现在我感觉自己学的
很散乱一样,可能这本书确实面向大佬,慢慢来吧。 好吧 大概就这些

发布了32 篇原创文章 · 获赞 6 · 访问量 919

猜你喜欢

转载自blog.csdn.net/EEEEEEcho/article/details/103837111