从一开始学习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模块。