本文主要介绍python原生数据结构列表和元组的特点以及对应的使用场景。
列表和元组是什么?
- 从抽象的数据结构层面来说,列表和元组都是“数组”,都是可以放置一组元素的有序集合。
- 而python语言的友好之一在于,这组集合的元素的类型不需要保持一致。
- 我们可以把不同类型的元素,比如整型和字符串,放入同一个列表或元组中。
l = [1, 2, 'hello', 'world'] # 列表中同时含有int和string类型的元素
l
# 输出
# [1, 2, 'hello', 'world']
tup = ('jason', 22) # 元组中同时含有int和string类型的元素
tup
# 输出
# ('jason', 22)
列表的特点
- 生成之后的可以不断往同一个列表中添加元素,也可以对列表中的元素进行修改和删除。
- 支持负数索引
- 支持切片操作
- 可以任意嵌套
元组的特点
- 生成之后,元组的内容不可变。
- 尝试修改元组元素会抛出异常
- 支持负数索引
- 支持切片操作
- 可以任意嵌套
列表和元组的共同点
在基本的存数和取数上,列表和元组是相似的:
- 支持元素不同类型
- 支持索引获取元素值
- 支持负数索引
- 支持切片操作
- 可以任意嵌套
与数据访问相关的操作也是有相同的内置函数/方法:
函数名称 | 函数功能 |
---|---|
count(element) | 统计列表或元组中某个element出现的次数 |
index(element) | 返回列表或元组中某个element第一次出现的索引 |
列表和元组的差异
- 由于列表是动态的,可以直接修改列表元素;
- 元组是静态的,生成之后不能直接修改原本的元组只能重新生成。
所以到修改元素相关的操作,列表有内置函数可以用于修改原列表,而元组需要借助外部函数来进行相关操作:
列表独有的函数名称 | 函数功能 |
---|---|
sort() | 将列表的内容按照一定的规则进行排序 |
reverse() | 将列表中的元素位置倒转 |
- 元组没有上述内置的排序和倒转方法,需要借助python内置的函数sorted()和reversed()来进行排序和倒转,会返回一个符合预期的新元组。
- sorted()和reversed()对列表同样适用,但是不是修改原列表,而是返回一个新列表。
列表和元组在存储上也有差异
- 由于列表是动态的,所以需要存储的信息比元组多,需要的存储空间自然也多。
- 相同大小的列表会比元组多需要额外存储一个指针,来指向对应的元素,同时还需要存储当前分配的空间中有多少空间已经被使用,才能在空间不足的时候分配更多的空间。
- 列表会实现额外分配一些空间,来避免频繁的空间分配操作。
所以我们会看到列表的存储空间会比元组多的同时,列表增加元素之后,占用的空间没有变化;元素越多的元组,占用的空间越大。
>>> l = [1, 2, 3]
>>> l.__sizeof__()
72
>>> tup = (1, 2, 3)
>>> tup.__sizeof__()
48
>>>
>>>
>>> l = [1,2,3,4]
>>> l.__sizeof__()
72
>>> tup = (1, 2, 3, 4)
>>> tup.__sizeof__()
56
>>>
列表和元组的性能差异
- 由于列表和元组的存储差异,导致了列表和元组在使用上会存在性能的差异。
- 同时这种差异会在元素量或者说列表和元组占用空间大的时候,差异会被放大。
同时,python对静态数据存在资源缓存。如果程序中的变量不被使用,python会回收它们占用的空间,返还给操作系统,在其他需要使用空间的时候由操作系统分配给python程序中的其他变量或给操作系统中的其他应用。
而元组作为一种静态数据,如果占用的空间不大,那么python会暂时缓存这部分的内存。当下次python需要同样大小的元组时,可以直接复用缓存的元组空间。
对比列表和元组初始化性能差异的代码如下:
python3 -m timeit 'x=(1,2,3,4,5,6)'
20000000 loops, best of 5: 9.97 nsec per loop
python3 -m timeit 'x=[1,2,3,4,5,6]'
5000000 loops, best of 5: 50.1 nsec per loop
列表和元组的使用场景
根据列表和元组的特点,我们可以看判断使用列表或元组时,主要看看存储的数据是否需要修改:
- 需要修改用列表
- 不需要修改使用元组
- 一些列举出来用于遍历的数据用元组,比如:方向 (up, down, left, right)
- 一些存储来只用来使用的数据用元组,比如:经纬度(longitude, latitude),数据库的字段值/列名
- 生成数据过程中的数据存储使用列表,比如:获取一组数中的满足某些条件的数,存储不断产生的程序日志等
好书推荐:
好课推荐:
写文不易,如果对你有帮助的话,来一波点赞、收藏、关注吧~👇