第3章 Python的数据结构、函数和文件
3.1 数据结构和序列
- 元组
元组是固定长度,不可改变的Python序列对象。创建元组的最简单方式,是用逗号分隔一列值:
当用复杂的表达式定义元组,最好将值放到圆括号内,如下所示:
用tuple可以将任意序列或迭代器转换成元组:
可以用方括号访问元组中的元素。和C、C++、JAVA等语言一样,序列是从0开始的:
元组中存储的对象可能是可变对象。一旦创建了元组,元组中的对象就不能修改了:
如果元组中的某个对象是可变的,比如列表,可以在原位进行修改:
可以用加号运算符将元组串联起来:
元组乘以一个整数,像列表一样,会将几个元组的复制串联起来:
对象本身并没有被复制,只是引用了它。
- 拆分元组
若想将元组赋值给类似元组的变量,Python会试图拆分等号右边的值:
即使含有元组的元组也会被拆分:
使用这个功能,可以很容易地替换变量的名字,其它与语言可能是这样:
但是在Python中,替换可以这样做:
变量拆分常用来迭代元组或列表序列:
Python最近新增了更多高级的元组拆分功能,允许从元组的开头“摘取”几个元素。它使用了特殊的语法*rest,这也用在函数签名中以抓取任意长度列表的位置参数:
rest的部分是想要舍弃的部分,rest的名字不重要。作为惯用写法,许多Python程序员会将不需要的变量使用下划线:
- tuple方法
因为元组的大小和内容不能修改,它的实例方法都很轻量。其中一个很有用的就是count(也适用于列表),它可以统计某个值得出现频率:
- 列表
与元组对比,列表的长度可变,内容可以被修改。你可以用方括号定义,或用list函数:
列表和元组的语义接近,在许多函数中可以交叉使用。
list函数常用来在数据处理中实体化迭代器或生成器:
- 添加和删除元素
可以用append在列表末尾添加元素:
insert可以在特定的位置插入元素:
插入的序号必须在0和列表长度之间。
警告:与append相比,insert耗费的计算量大,因为对后续元素的引用必须在内部迁移,以便为新元素提供空间。如果要在序列的头部和尾部插入元素,可能需要使用collections.deque,一个双尾部队列。
insert的逆运算是pop,它移除并返回指定位置的元素:
可以用remove去除某个值,remove会先寻找第一个值并除去:
若不考虑性能,使用append和remove,可以把Python的列表当做完美的“多重集”数据结构。
用in可以检查列表是否包含某个值:
否定in可以再加一个not:
在列表中检查是否存在某个值远比字典和集合速度慢,因为Python是线性搜索列表中的值,但在字典和集合中,在同样的时间内还可以检查其它项(基于哈希表)。
- 串联和组合列表
与元组类似,可以用加号将两个列表串联起来:
若已经定义了一个列表,用extend方法可以追加多个元素:
通过加法将列表串联的计算量较大,因为要新建一个列表,并且要复制对象。用extend追加元素,尤其是到一个大列表中,更为可取。因此:
要比串联方法快:
- 排序
可以用sort函数将一个列表原地排序(不创建新的对象):
sort有一些选项,有时会很好用。其中之一是二级排序key,可以用这个key进行排序。例如,可以按长度对字符串进行排序:
- 二分搜索和维护已排序的列表
bisect模块支持二分查找,和向已排序的列表插入值。bisect.bisect可以找到插入值后仍保证排序的位置,bisect.insort是向这个位置插入值:
注意:bisect模块不会检查列表是否已排好序&#