深刻理解python之二——python列表和元组

从一开始学习python的时候,不少人就听到的是元组和列表差很少,区别就是元组不能够改变,列表能够改变。python

从数据结构来讲,这二者都应当属于数组,元组属于静态的数组,而列表属于动态数组。稍后再内存的分配上也会体现这一点。对于这两种类型,除了能接受相同类型的值以外,也接受混合类型的值。算法

元组

说元组不能改变的,其实只是看到了操做结果显示出来的表面现象。能够来看一下下列的操做(输出结果截去了相同的高几位)。编程

a = (1,2,3)
b = (1,2,3)
c = a+b
id(a)
>>>71845752
id(b)
>>>99964864
id(c)
>>>97883880

这样的结果意味着,对于元组,即使元组组成的值是相同的,每次绑定一个变量都是从新开辟空间生成一个新的。在执行a+b的元组组合操做时,也是在从新建立一个新的元组,而不是在前一个的基础上拼接的。也就是说全部的内容都会被复制一份,因此这里的复杂度不是O(1),而是O(n)。python3.x

此外,元组还有一个额外要注意的细节。在《Python高性能编程》一书中做者提到了1-20长度的小元组在被回收以后不会返还给操做系统处理,而是在程序内保留。这一细节多是根据python2.7来讲的,对于python3.x版本未验证。元组通常会缓存在Python的运行时环境中,使用的时候不用去访问内核来分配内存。数组

列表

列表主要的操做时增删,切片,查找,排序。前二者依赖于列表的组织结构。因为列表是可变的,因此列表除了自己的数据以外,每一个数据单元还会额外消耗一个单位的单元用于保存结构信息,以便列表进行从新调整大小。因此假如一样保存10W数据,列表实际占用的数据单元是远大于10W这个数。缓存

对于列表的增长,主要是一个append()方法,涉及一个动态申请空间的算法。每次使用.append()操做的时候就会申请空间,申请老是按照必定的算法申请远不止一个空间,便于接下来的扩展。这点在初学数据结构的时候可能都会知道,一次申请最好申请一个差很少的,这要比一个一个申请更有效,不过具体数量是多少,这多是一个奥卡姆剃刀的问题。预测式的空间申请算法,会带来必定的额外空间开销。数据结构

列表的.index()方法提供了一种搜索调用,但它的实现是线性搜索,效率并不高。app

列表的排序方法使用的是Tim排序,相对来讲是一种比较好的实现。python2.7

列表在加载的时候,相对于元组的速度也是慢了许多。性能

最后

对于二者其实均可以经过本身编写安排引入算法来进行搜索或排序。若是本身编写有点困难,也能够借助内建的bisect模块。

相关文章
相关标签/搜索