首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python元组和列表你真的用对了吗?

对于Python来说,列表可谓是用到的非常多的数据结构之一了,但是Python还有另外一个数据结构叫做元组,直观表现来说,元组就像是不可变的列表,那么问题来了,元组和列表的区别是什么呢?什么时候应该用元组,什么时候应该用列表呢?我在刚开始学习Python的过程当中一直有这种困惑,本文是我总结的一些关于Python列表和元组的相关知识,下面来一起看一下吧。

基础知识

总的来说,列表和元组实际上都是「一个可以放置任意数据类型的有序数组」, 相比于其他语言,比如说C或者Java等等,他们数组中的元素类型必须保持一致,而Python当中并不存在这个限制,可以在里面放任意的元素。

从表现形式上看来,数组用的是中括号()而元组用的是小括号(),他们的区别如下:

「列表是可变的(mutable)」, 长度大小不固定,可以任意的增删改元素

「元组是不可变的(immutable)」, 长度大小固定, 无法对元素删减或者改变

我们通过一个具体的样例来看一下上面的区别,对于列表,我们很容易的利用索引修改当中的元素,而对于元组来说,如果对它进行修改操作,则会触发错误,原因就是元组是不可变的。

我们利用colab来演示结果:

那么问题来了,元组一旦被创建就无法对它进行做任何的改变, 那么如果我们想改变元组当中的值,又该如何操作呢?那只能重新开辟一块内存,创建新的元组了, 同样我们来看下面的一个例子:

可以发现,对于列表进行增加元素的操作,列表本身的内存地址并没有发生改变,而对于元组来说,它本身的内存地址发生了改变,也就符合上面所说的,如果想要对元组中的元素进行新增操作,则会重新开辟一块内存。

基本操作

下面来简单介绍一下列表和元组中的一些常用的基本操作。

索引

对于Python的列表和元组来说,有一个非常强大的功能就是「支持负数索引」,其中表示最后一个元素, 表示倒数第二个元素,以此类推。

切片

除了索引,Python当中的元组和列表还支持「切片操作」,对于这个我不打算在这里面详细去说,仅介绍简单的基础用法,如有需求,请参考官方文档。

相互转换

对于列表和元组,可以使用和来进行相互的转换。

内置函数

下面,我们来看一下列表和元组中的内置函数,这里我只介绍一些比较常用的,对于其他的可以参考官方文档。

表示统计列表/元组中元素出现的个数

返回列表/元组元素第一次出现的索引

&

这两个函数分别对列表的元素进行正序排列和逆序排列(元组是没有这两个函数的, 原因是他会改变列表本身)

&

这两个函数是对于列表和元组进行排序的函数,返回的是迭代器, 而返回的是列表。

下面我们来看一下具体的样例:

列表和元组的存储方式

由于列表和元组的特性,列表是可变的,而元组是不可变的,这种差异必然是由于底层的存储方式不同而决定的,首先我们来看下面的样例。

我们可以看到,元组相对于列表来说,在放置相同元素的情况下,元组所占用的空间比列表少了16个字节,主要原因是由于列表是动态的,因此对于列表的存储需要指针,用来指向对应的元素,这里我们存放的是类型,占用了8个字节,其次由于列表的可变性,需要额外的存储来保存已经分配的长度大小的信息(8个字节),这样才能在空闲长度不足的情况下及时的分配内存开辟空间,我们来看下面的一个例子:

我们可以发现,Python为了减少每次列表扩容导致的开销,每次会多分配一定的内存,这样的机制保证了其操作的高效性。而对于元组来说,它本身是不可变的,因此存储空间固定。

列表和元组的性能分析

通过上文对于存储差异的分析,我们可以认为,元组要比列表要更加的轻量一些,因此,总的来说,元组的性能要稍好于列表。

我们来看下面一个列子

这段代码是在我的电脑上运行的,不同的电脑可能会有差异,但是我们可以看出,对于元组的初始化操作要比列表快5倍左右,原因主要是因为Python会对于一些静态数据做「资源缓存」, 对于元组来说,当它占用的空间不大的时候,Python会暂时缓存这一部分内存,当下次请求同样大小的元组的时候,Python无需向系统再次申请这一部分内存,从而提高了程序的运行效率。

当然,如果对于增删操作来说,列表是优于元组的,原因显而易见,元组是需要重新开辟内存,而列表缺不需要这样。

列表和元组的使用场景

上面分析了这么多,那么什么时候应该用元组,什么时候应该用列表呢?这里当然需要具体情况具体分析。

如果存储的数据和数量不变,比如保存图片中所有像素点的rgb值,这个显然是利用元组比较合适一些

如果数据的数量可变,比如需要统计或者计算出来的结果保存,那么显然是利用列表更加合适一些

总结

对于Python当中的元组和列表,从表现形式来看,仅仅只有列表是可变的,而元组是不可变的,但是这个表面特性是由于内部实现而决定的,因此也就造成了对于某些操作的性能差异,因此在选择数据结构的过程中,应该去考虑这一点,选择更加合适的数据结构,总的来说,列表和元组的区别可以总结为如下两点:

列表是可变的,可以任意增加或者删除元素,因此存储空间要略大于元组

元组是不可变的,无法对元素进行增加或者删除,更加轻量,适合保存不变的数据

文章最后,来看一个例子,下面的程序运行结果是怎么样的呢?

t变成

因为tuple不支持对他的元素赋值,因此会触发TypeError异常

两个都是错的

两个都是对的

参考资料

Fluent Python By Luciano Ramalho

Python 官方文档

Lists vs Tuples in Python

Optimization tricks in Python: lists and tuples | Artem Golubin

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20201028A067TD00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券