从宏观设计哲学上讲,元组(tuple)用于描述一个不会改变的事物的多个属性,列表用于保存多个相互独立对象的数据集合。
列表示动态数组,元组是静态数组。元组相当于不支持元素添加、修改、删除等操作的列表。
元组的底层数据结构如下:
可以看出,底层是一个变长对象,同时是一个不可变的对象。
typedef struct { PyObject_VAR_HEAD PyObject *ob_item[1];} PyTupleObject;//元组底层结构
列表的底层数据结构如下:
可以看出,底层是一个变长对象,但是一个可变对象。
typedef struct { PyObject_VAR_HEAD PyObject **ob_item; Py_ssize_t allocated;} PyListObject;//列表底层结构
对于元组来说,它的底层结构定义非常简单,一个引用计数,一个类型,一个指针数组,定义中的1相当于我们前面学习的柔性数组。元组中没有allocated,因为它是不可变的,不支持resize操作。列表中的二级指针指向一个对象的数组,元组中的一级指针指向具体的值。
元组存在最大的一个特点就是可以作为字典的key,以及作为集合的元素。因为字典和集合存储数据的原理基于哈希表,关于字典和集合我们慢慢学习。如果对象是 可变的,像列表一样,那么哈希值也会变化。当我们希望字典的key是一个序列时,它的哈希值不变,只能是元组来充当。
元组的另外一个特点是分配速度比较快,这由两方面来决定的。一是元组示不可变的,编译时候就确定了;二是元组还拥有我们前面说到的空闲对象缓冲池。元组是静态数组,当不使用且占用空间不大时,系统会暂时缓存这部分内容。下次创建同样大小的元组时,不用内存分配,直接向系统请求即可。