列表和元组基础
列表和元组都是可以放置任意数据类型的有序集合。
1 | l = [1, 2, 'hello', 'world'] # 列表中同时含有 int 和 string 类型的元素 |
两者的区别如下:
- 列表是动态的,长度大小不固定,可以随意增加、删除或者更改元素(mutable)。
- 元组是动态的,长度大小固定,无法增加删除或者改变(immutable)。
1 | l = [1, 2, 3, 4] |
如果我们想修改元组中的元素,就需要重新申请一片内存,但对于列表,我们就可以直接插入新的元素:
1 | tup = (1, 2, 3, 4) |
列表和元组的存储方式
列表是动态的,元组是静态的,这一差别会影响其存储方式:
1 | l = [1, 2, 3] |
由于列表要存储可变长度的元素,所以需要额外的指针来存储下一个元素的位置(int型的指针占8个字节);除此之外,还需要存储已经分配的长度大小(8个字节),因而相对于元组来说,列表要消耗更多的内存。对于列表来说,当空间不足时会重新分配新的空间。
1 | l = [] |
为了减少每次插入元素时反复申请空间所带来的额外开销,Python会给列表分配额外的空间,这样的机制称为(Over-allocating)。而对于元组来说,由于存储的数目不可变,因而空间大小固定。
两者的存储差距在面对巨量的数据规模时会更加明显。
列表和元组的性能
因为存储方式上的差异,总体上来说,元组的性能要优于列表。
Python在进行内存管理时,会对静态数据进行资源缓存。对于Python来说,如果一些变量不再被使用时,便会调用垃圾回收机制对这些变量进行回收。但对于元组等静态变量,当其不再被使用且大小不大的情况下,Python会对其进行缓存,从而在下次申请同样大小的内存时直接对缓存的空间进行操作,而不用返回申请内存,进而提升了效率。
列表和元组的适用场景
- 如果所要存储的数据不大且不变时,选择元组更合适;
- 如果数据需要经常改动,选择列表更合适。
思考
list()
和[]
创建列表的区别:
区别主要在于list()
是一个function call,Python的function call会创建stack,并且进行一系列参数检查的操作,比较expensive,反观[]
是一个内置的C函数,可以直接被调用。