@Author :Runsen
上面四篇文章总结了Python的基础。
在Pthon中数据结构是非常重要的,所以下面将深入Pyhon数据结构
Python列表和元组总结
列表是动态的,长度大小不固定,可以随意地增加、删减或者改变
而元组是静态的,长度大小固定,无法增加删减或者改变
定义列表和函数
l = [1, 2, 'hello', 'world'] # 列表中同时含有 int 和 string 类型的元素 l [1, 2, 'hello', 'world'] tup = ('jason', 22) # 元组中同时含有 int 和 string 类型的元素 tup ('jason', 22)对于列表来说,由于其是动态的,我们只需简单地在列表末尾,加入
对于元组来说,实际上就是创建了一个新的元组,然后把原来两个元组的值依次填充.
tup = (1, 2, 3, 4) new_tup = tup + (5, ) # 创建新的元组 new_tup,并依次填充原元组的值 new _tup (1, 2, 3, 4, 5) l = [1, 2, 3, 4] l.append(5) # 添加元素 5 到原列表的末尾 l [1, 2, 3, 4, 5]Python 中的列表和元组都支持负数索引,列表和元组都支持切片操作
l = [1, 2, 3, 4] l[-1] 4 tup = (1, 2, 3, 4) tup[-1] 4 list = [1, 2, 3, 4] l[1:3] # 返回列表中索引从 1 到 2 的子列表 [2, 3] tup = (1, 2, 3, 4) tup[1:3] # 返回元组中索引从 1 到 2 的子元组 (2, 3)元组的初始化速度,要比列表快 5 倍。
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因此如果存储的数据和数量不变,选择元组
如果存储的数据或数量是可变的,选择列表
下面有两种方法创建列表,哪个初始化更快,运行时间更快。
# 创建空列表 # option A empty_list = list() # option B empty_list = []测试结果,虽然直接创建元组初始化速度最快,但是由于要用list函数转一道反而不如直接创建列表的速度快。
在Python有个重要的东西,就是对象的深浅拷贝。
我们就称为:’==’ vs ‘is’
== 比较对象之间的值是否相等is 比较的是对象身份是否相等,它们是否同一个对象我们一般通过id来是否相等来判断是否同一个对象
a = 10 b = 10 a == b True id(a) 4427562448 id(b) 4427562448 a is b True注意a is b == True 只适合和用于-5 到256之间,这个不知道你是否知道,我觉得面试官肯定不知道。
a = 257 b = 257 a == b True id(a) 4473417552 id(b) 4473417584 a is b False下面我们说下,浅拷贝和深拷贝
l1 = [1, 2, 3] l2 = list(l1) l2 [1, 2, 3] l1 == l2 True l1 is l2 False s1 = set([1, 2, 3]) s2 = set(s1) s2 {1, 2, 3} s1 == s2 True s1 is s2 False浅拷贝指重新分配一块内存,l2 就是l1的浅拷贝,但是只要是序列的浅拷贝,他们的id就是不一样的。
对于深拷贝,在python中提供了对应的函数copy.copy()
import copy l1 = [1, 2, 3] l2 = copy.copy(l1) t1 = (1, 2, 3) t2 = tuple(t1) t1 == t2 True t1 is t2 True元组(1,2,3)只被创建一次,t1和t2同时指向这个元组,反正你看到copy.copy()就是两个True
这里有一个天天来骗小孩的东西,就是l1变了,l2变不变的问题
我这里在使用的嵌套列表
l1 = [[1, 2], (30, 40)] l2 = list(l1) l2 [[1, 2], (30, 40)] l1.append(100) l1[0].append(3) l1 [[1, 2, 3], (30, 40), 100] l2 [[1, 2, 3], (30, 40)]l2竟然变了,这是为什么。首先初始化一个列表l1,里面的元素是一个列表和元组,然后对l1执行浅拷贝,赋予了l2 ,但是l2中的元素和l1指向同一个列表和元组对象,只有列表对象变,你浅拷贝就要跟着我变。
如果你添加一个序列来,我浅拷贝没有指向你新来的对象。我干嘛跟着你变。
l1.append(100)l1的列表新增元素100,不会对l2产生影响,l1和l2是两个不同的对象
如果我在元组加呢???
l1[1] += (50, 60) l1 [[1, 2, 3], (30, 40, 50, 60), 100] l2 [[1, 2, 3], (30, 40)]竟然不会变,说白了只有列表对象变,难道元组不可变你不知道?
深度拷贝,就是你爱怎么变,就去哪里变,我就不变了。
import copy l1 = [[1, 2], (30, 40)] l2 = copy.deepcopy(l1) l1.append(100) l1[0].append(3) l1 [[1, 2, 3], (30, 40), 100] l2 [[1, 2], (30, 40)]因为此时l1和l2完全独立了,没有任何影响
总结起来其实就是两句话
浅拷贝,不可变的不可变,可变的依旧可变深拷贝,都不可变 刘润森! 认证博客专家 Python Java 前端 17年就读于东莞XX学院化学工程与工艺专业,GitChat作者。Runsen的微信公众号是"Python之王",因为Python入了IT的坑,从此不能自拔。公众号内容涉及Python,Java计算机、杂谈。干货与情怀同在。喜欢的微信搜索:「Python之王」。个人微信号:RunsenLiu。不关注我公号一律拉黑!!!