有了列表,为什么 Python 还有元组?

Python中有一个基础的数据结构 , 叫做元组(tuple) , 但是一般挺少有人会去用它的 , 因为在开发过程中 , 列表(list)基本已经能够满足我们的需求 。
即使是这样 , 你也千万不要就此认为元组是多余的 。 不然在面试中也不会经常被人问 , 元组和列表有啥区别?为什么需要元组?
以下两点 , 第一点是大家所熟知的 , 而第二点可能只有老司机才会知道 , 只有学习了第二点 , 才算真正理解了元组存在的价值和意义 。
1. 不可变列表这是元组区别于列表最显著的特征 。

  • list:可变的序列
  • tuple:不可变的序列
那什么是不可变的序列呢?
那就是在元组对象生成后 , 诸如列表的插入元素删除元素添加元素清空元素修改元素等功能 , 在元组中通通没有 , 你是无法对其进行修改的 。
由于元组是不可变的 , 所以其方法也是很有限的 。 这里罗列一下 。
# s1和s2都是元组s1=(1,2,3)s2=(4,5,6)# 拼接生成新元组s1+s2s1.__add__(s2)# 是否包含2 in s1s1.__contains__(2)# 统计元素包含的次数s1.count(2)# 获取元素s1[0]s1.__getitem__(0)# 找到2第一次出现的索引s1.index(2)# 获取长度len(s1)# 重复拼接s1*n2. 具名元组这个特性 , 我个人认为 , 才是元组存在的意义所在 。
只讲 具名元组 , 可能不太好理解 。 如果称之为 带字段名的记录 , 你可能就清楚了 。
这里举个例子 , 但是实现带字段名 , 需要一个库(collections)的支持 , 你需要导入它 。
from collections import namedtuple# 生成一个City类City = namedtuple("City", "name country polulation coordinates")# 实例化tokyo = City("Tokyo", 'JP', '36.93', ('35.68','139,69'))print(tokyo)# City(name='Tokyo', country='JP', polulation='36.93', coordinates=('35.68', '139,69'))print(tokyo.name)# Tokyo看着有点像字典 , 是不是 , 但是他不是字典(获取数值的方法也与字典不同) , 字典是可变 。 元组在创建后 , 就无法再对其进行修改 。 这在某个程度上说明元组适合存放那些无需修改的数据 。 比如上面的 , 地名 , 国家 , 经纬度 。
除了上面的用法之处 , 这里还要介绍一些元组自己专有的属性 。
# 打印字段名print(City._fields)('name', 'country', 'polulation', 'coordinates')# 生成新实例LatLong = namedtuple('LatLong', 'lat long')Xiamen_tuple = ('Xiemen', 'China', '40,54', LatLong(24.26,118.03))Xiamen = City._make(Xiamen_tuple)print(Xiamen)# City(name='Xiemen', country='China', polulation='40,54', coordinates=(24.26, 118.03))# 将具名元组转为OrderDictXiamen_dict = Xiamen._asdict()print(Xiamen_dict)# OrderedDict([('name', 'Xiemen'), ('country', 'China'), ('polulation', '40,54'), ('coordinates', LatLong(lat=24.26, long=118.03))])总结一下 , 元组是一种很强大的可以当作记录来用的数据类型 , 这才是他存在的价值和意义所在 。 而为人所熟知的 , 它的第二个角色才是充当一个不可变的列表 。 (以上都是个人看法 , 如有不同见解 , 欢迎留言讨论)
文末福利本人原创的 《PyCharm 中文指南》一书前段时间一经发布 , 就火爆了整个 Python 圈 , 发布仅一天的时间 , 下载量就突破了 1000, 并且在当天就在 Github 上就收获了数百的 star , 截至目前 , 下载量已经破万 。
这本书一共将近 200 页 , 内含大量的图解 , 制作之精良 , 值得每个 Python 工程师 人手一份 。


推荐阅读