Python进阶系列---(1)列表与元组

Python进阶系列—(1)列表与元组

一、列表和元组基础

列表和元组,都是一个可以放置任意数据类型的有序集合。

1、区别

列表:动态,长度大小不固定(mutable)
元组:静态,长度大小固定,无法增删(immutable)

2、操作

对元组进行操作,实际创建了一个新元组,然后进行填充。

两者可以通过list()和tuple()函数相互转换。

3、常用方法

count(item) :统计列表 / 元组中 item 出现的次数。

index(item)表示返回列表 / 元组中 item 第一次出现的索引。
list.reverse()list.sort() 分别表示原地倒转列表和排序(注意,元组没有内置的这两个函数)。

reversed()sorted() 同样表示对列表 / 元组进行倒转和排序,reversed() 返回一个倒转后的迭代器。sorted() 返回排好序的新列表。

二、存储方式差异

在这里插入图片描述
在这里插入图片描述
列表是动态的,需要存储指针,指向对应的元素(上述为int型,8字节)。

另外,由于列表可变,需要额外存储以及分配的长度大小(8字节),这样可以试试追踪列表空间的使用情况,当空间不足时,及时分配额外内存。
分配机制:over-allocating,增加/删除都为O(1)。
而元组长度大小固定,元素不可变,所以存储空间固定。

具体分析:

l = []
l.__sizeof__() // 空列表的存储空间为40字节
40
l.append(1)
l.__sizeof__() 
72 // 加入了元素1之后,列表为其分配了可以存储4个元素的空间 (72 - 40)/8 = 4
l.append(2) 
l.__sizeof__()
72 // 由于之前分配了空间,所以加入元素2,列表空间不变
l.append(3)
l.__sizeof__() 
72 // 同上
l.append(4)
l.__sizeof__() 
72 // 同上
l.append(5)
l.__sizeof__() 
104 // 加入元素5之后,列表的空间不足,所以又额外分配了可以存储4个元素的空间

三、性能比较

元组比列表轻量一些,总体性能略优于列表。
python在后台,会对静态数据做一些资源缓存(resource caching)。 对于一些静态变量,比如元组,如果不被使用并且占用空间不大时,会暂时缓存这部分内存。

**初始化**一个相同元素列表和元组所用时间:

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

**索引操作**,差别非常小:

python3 -m timeit -s 'x=[1,2,3,4,5,6]' 'y=x[3]'
10000000 loops, best of 5: 22.2 nsec per loop
python3 -m timeit -s 'x=(1,2,3,4,5,6)' 'y=x[3]'
10000000 loops, best of 5: 21.9 nsec per loop

注:此处使用timeit标准库,默认会关掉垃圾回收机制,使时间计算更加准确。不过,好像windows平台有限制,初始化时时间相差不大,在linux和mac里比较明显。

四、使用场景

1、如果存储的数据和数量不变,适合使用元组。
比如一个函数返回一个地点的经纬度。
2、如果存储的数据或数量可变,适合用列表。

五、创建空列表效率

# 创建空列表
# option A
empty_list = list()
# option B
empty_list = []

A方式优于B方式,原因在于list()是一个function call,会创建stack。反观[]是一个内置的C函数,可被直接调用,效率高。

六、说明

l = [1,2,3]消耗64字节,而l.append(1),l.append(2),l.append(2)消耗72字节?

因为列表的over-allocate在加入新元素后,解释器判断当前存储空间不够,额外分配的空间。l.append(1),l.append(2),l.append(2)实际分配了四个元素空间,而l = [1,2,3]直接初始化,只分配三个元素空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值