Python列表和元组的使用

列表和元组

对于一门编程语言来说,数据结构都是其根基。
  • python提供的数据结构有列表(list)、元组(tuple)、字典(dict)、集合(set),

  • 而这篇文章就记录一下列表和元组的特性和用法,以备不时之需。

首先,你要知道,python提倡万物皆对象,所以列表也是一个对象。

什么是列表?

列表是一个可以放置任意数据类型的有序集合。在大多数编程语言中,集合的数据类型必须一致。不过因为python是一门动态类型的编程语言,倒是无此要求。

列表的创建:

l = []
l = list()
l1 = [1,2,3,4,5]
所以
  • []和list()这两种创建方法有什么区别呢?

区别主要在于list()是一个function call,python的function call会创建stack,并且进行一系列参数检查的操作,比较expensive,反观[]是一个内置的c函数,可以直接被调用,因此效率高。

列表的操作方法有两种:

​ 1.通用序列操作

​ 2.list模块自带的方法

通用序列操作分别是索引(indexing)、切片(slicing)、相加(add)、相乘(multiply)、成员资格检查。

序列操作

# 索引 [0]
>>>l = [0, 1, 2, 3, 4, 5]
>>>l[0]
1
>>>l[-1]
5
>>>l[1] = 10
>>>l
[0, 10, 2, 3, 4, 5]
'''
索引是从0开始递增而非从1开始,习惯了就好了。而-1则是表示取最后一位。
索引不能超出序列的个数,否则会出错
使用内置函数len()可以得到列表个数
'''
len(l)
6

# 切片 [:]
# 切片使用:冒号来间隔
>>>l = [0, 1, 2, 3, 4, 5]
>>>l[1:5]
[1, 2, 3, 4]
>>>l[0:2]
[0, 2, 4]
'''后面那个2是步长,隔1个选1个'''
>>>l[::-1]
[5, 4, 3, 2, 1, 0]
'''反选'''

# 相加 +
>>>[1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]

# 乘法 *
>>>[1,2,3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]

# 成员资格检查 in
>>>for i in l:
>>>    print(i)
0
1
2
3
4
5

列表方法

# 使用dir()函数可以查看模块所有的方法

>>>dir(list)
'''
然后一一练习罢
append()	追加
clear()		清空
copy()		浅拷贝
count()		计数
extend()	合并列表
index()		返回元素的第一个索引
insert()	指定索引插入元素
pop()		删除最后一个元素并返回
remove()	指定元素删除
reverse()	反向
sort()		排序
sort(reverse=True)	排序
'''

什么是元组?

​ 元组跟列表一样都是序列,只是列表的元素可以随意更改,而元组的元素是不可修改的。

元组的创建:

# 用逗号隔开元素就能创建元组
>>>1, 2, 3
(1, 2, 3)

# 通常用圆括号括起创建
>>>(1, 2, 3)
(1, 2, 3)

# 空元组
>>>()
()

# 单个元素元组
>>>(1,)
(1,)

>>>tuple([1, 2, 3])
(1, 2, 3)

元组的使用:

>>>t = (1, 2, 3)
>>>t[1]
2
>>>t[0:2]
(1, 2)

列表和元组存储方式的差异

​ 列表和元组最重要的区别就是,列表是动态的、可变的,而元组是静态的、不可变的。这样的差异,会影响两者的存储方式。

l = [1, 2, 3]
l.__sizeof__()
64
tup = (1, 2, 3)
tup.__sizeof__()
48
  • 对列表和元组,我们放置了相同的元素,但是元组的存储空间,却比列表要少16字节。
  • 事实上,由于列表是动态的,所以它需要存储指针,来指向对应的元素(上述例子中,对于int型,8字节)。另外,由于列表可变,所以需要额外存储已经分配的长度大小(8字节),这样才可以实时追踪列表的使用情况,当空间不足时,及时分配额外空间。
l = []
l.__sizeof__()	// 空列表的存储空间为40字节
40
l.append(1)
l.__sizeof__()
72	// 加入了元素1之后,列表为其分配了可以存储4个元素的空间
l.append(2)
l,__sizeof__()
72	// 由于之前分配了空间,所以加入元素2,列表空间不变
l.append(4)
l.__sizeof__()
72	//不变
l.append(5)
l.__sizeof__()
104 // 加入元素5之后,列表的空间不足,所以又额外分配了可以存储4个元素的空间
  • 通过上述的例子,我们看到了列表空间的分配过程。为了减小每次增加、删除操作时空间分配的开销,python每次分配空间时都会额外多分配一些,这样的机制(over-allocating) 保证了其操作的高效性:增加/删除的时间复杂度均为O(1)
  • 但是对于元组,情况就不同了。元组长度大小固定,元素不可变,所以存储空间固定。

列表和元组的性能

  • 列表和元组在存储方式上的差异,让我们知道元组要比列表更加轻量级一些,所以总体上说,元组的性能速度略优于列表。

  • 并且因为元组是不可变的,在安全性上元组是比列表好的。

  • 另外。python会在后台,对静态数据做一些资源缓存(resource caching)。通常来说,因为垃圾回收机制的存在,如果一些变量不被使用了,python就会回收它们所占用的内存,返还给操作系统,以便其他变量或者其他应用使用。

  • 但是对于一些静态变量,比如元组,如果它不被使用并且占用空间不大时,Python会暂时缓存这部分内存。这样,下次我们再创建同样大小的元组时,Python就可以不用再向操作系统发出请求,去寻找内存,而是可以直接分配之前缓存的内存空间。这样就能大大加快程序的运行速度。

来看看计算初始化一个相同元素的列表和元组分别所需的时间。

python3 -m timeit 'x=(1,2,3,4,5,6)'
100000000 loops, best of 3: 0.00917 usec per loop
python3 -m timeit 'x=[1,2,3,4,5,6]'
100000000 loops, best of 3: 0.00919 usec per loop

看上去差别不大,啊哈哈哈。

列表和元组的使用场景

  • 根据上面说的特性,来分析一下。

1.如果存储的数据和数量不变,那么肯定选用元组

2.如果存储的数据或数量是可变的,那么肯定选用列表

关于list和tuple的内部实现

1.list和tuple的内部实现都是array的形式,list因为可变,所以是一个over-allocate的array,tuple因为不可变,所以长度大小固定。这里有源码链接,可以去看看。

https://github.com/python/cpython

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值