Python序列拾遗 --流畅的python
最近看
序列类型分类
首先,python中的列表类型有很多种,一种常见的分类方法是将它们分为容器序列和扁平序列,它们的区别可以由一张表来表示:
容器序列 | 扁平序列 |
---|---|
list,tuple,collections.deque | str, bytes, bytearray, memortyview, array.array |
能够存放不同类型的数据 | 只能容纳一种类型 |
存放的是对象的引用 | 存放的是值 |
内存空间可以不连续 | 连续的内存空间 |
除了这种分类,还有一种常见的分类,即将他们分为可变序列和不可变序列. 可变序列包括list,bytearray,array.array,collections.deque, memoryview
, 不可变序列包括tuple,str,bytes
.
列表推导
列表推导是一种常见的使用列表的方式, 常用来构建列表. 虽然它做的事情使用有map,filter
组合的lambda表达式也都能做到,但是列表推导在可读性上有着很大的优势,例如:
1 | numbers = list(range(10)) # 构建一个0~9的列表 |
当然,我们在使用列表推导生成较大的序列时会占用较大内存,因为此时我们是建立一个完整列表再将其传递出去,使用生成器表达式可以节省内存,因为此时它可以逐个生成元素, 生成器表达式的语法和列表推导基本一致,只要把方括号[]
改为圆括号()
即可.
元组
提到元组我们一般都将其当做不可变的列表,但是它往往可以当成一种数据记录来加以利用,甚至collections
提供的具名元组可以迅速实现一个简单的带属性的类供调试.
1 | from collections import namedtuple |
City(name='Beijing', country='China', population='2171')
排序相关
两种常用的排序是list.sort
和sorted
,二者使用同样的排序算法(都使用timesort算法,该算法会自适应地根据数据特点交替使用插入和归并排序,这对来自现实的具有一定数据特点的序列非常有效,但在完全随机的序列排序上不如快速排序), 其主要不同是,list.sort
是就地排序,直接改动原列表;而sorted
则会将源列表复制一份,返回新的有序列表.
在将数据完成排序后, bisect
包中的bisect
和insort
函数常用来在有序列表中进行查找和插入, 二者都基于二分算法.
列表之外
通常我们都使用list作为我们的序列类型, 因为它灵活而简单,但是在需求更明确或追求更高效率时,记住我们还有其他更优的选择也不是坏事.
- 数组 常用于我们需要只包含数字的列表时,
array.array
比list
更高效, 且支持直接从文件读写. - 双向队列
collections.deque
常用于需要经常从两端增删元素的场景,它高效而且线程安全,常被用来实现队列和堆栈的操作. - Numpy数组 numpy数组是科学上最常用的科学计算库之一了,常用来处理科学计算,在处理数字时其功能的全面和效率之高都远超python的原生序列.