Python数据类型第1篇元组和列表的性能分析命名元组
目录一、元组和列表1。元组和列表的性能分析2。为什么列表在Python中是最常用的呢?3。timeit里面有个Timer类4。timeit里面还有个直接用的timeit的方法,timeit。timeit()5。这2个方法有啥区别?二、命名元组三、命名元组有什么特点?一、元组和列表
元组vs列表1。元组和列表的性能分析
元组和列表用来存储数据,在元组和列表里面查询的时候,到底哪个更快呢?
计算创建元组和列表所需的时间:ipython中使用timeit这个命令。
计算时间模块介绍:importtimeittimeit。timeit
可以用这个模块来测试函数的性能。安装ipythonpipinstallipython
ipython是个交互环境,就跟我们输入Python进去是一样的。只不过它外面做了一层封装,比Python交互环境更好用一点。
ipython里面有一个命令叫做timeit,后面可以跟一个Python表达式。
例如定义一个列表在后面:
敲完这行命令,返回了一行时间。这个是在内存中初始化一个列表,如图可以看到创建了一千万次,时间是48。4ns
可以看出,创建一个元组比创建一个列表要快得多。
元组的速度比列表要快3倍多。在内存里,当我们创建一个列表的时候,会划分一块区域出来,拿一块区域给列表来储存值。例如初始化,里面给它留了20个位置在这个列表里面储存值。
列表占用内存如图
当储存到一定程度,Python解释器检测到列表快要盛满了的时候,它会对列表做一个扩容。
给扩容到200,当存储到150的时候,发现又快存储满了,又会给你继续扩容。
随着数据的增多,底层会不断给这个列表扩容。
初始化一个元组,同样也是一千万次,只需12。8ns
元组是一个不可变的类型。
比如定义的元组里面有3个元素,Python解释器在给它分内存的时候,就给它分了3个格子。
这里面只能存3条数据,就这么大,所以元组占用的内存比列表要少。
元组和列表内存占用对比图
用一个列表存储50条数据和用一个元组存储50条数据,那么元组占用的内存要比列表小得多。2。为什么列表在Python中是最常用的呢?
因为列表比较灵活,用列表的话,可以往里面不断得添加元素。如果元素固定的,那就用元组。3。timeit里面有个Timer类。
来看看这个类的源码:
timerdefaulttimer代表的是:创建一个列表、元组等,它要执行的一个次数。
看源码,默认是一千万次:
importtimeit这个模块可以用来做性能分析deffunc():foriinrange(10):print(i)这个对象有个方法叫做timeitrestimeit。Timer(func)。timeit(100)把这个func函数传进去,运行100次,然后返回的是个时间timeit。Timer(func)。timeit(100)中函数func是不需要加引号的,如果是字符串、列表这些需要加引号放进去print(res)
可以看到运行100次需要的时间是:0。0043269999999999975
4。timeit里面还有个直接用的timeit的方法,timeit。timeit()importtimeit这个模块可以用来做性能分析deffunc():foriinrange(10):print(i)这个对象有个方法叫做timeitrestimeit。Timer(func)。timeit(100)把这个func函数传进去,运行100次,然后返回的是个时间timeit。Timer(func)。timeit(100)中函数func是不需要加引号的,如果是字符串、列表这些需要加引号放进去print(res)res2timeit。timeit(〔1,2,3〕)print(res2)
这个模块的作用:大家写的功能函数,可以用它测下功能函数的速度,执行大概要多久。
默认是一千万次,结果如下:
如果列表不加引号直接传是会报错的:
提示不可被调用!5。这2个方法有啥区别?
其实它们是一个东西。
二、命名元组
元组的性能是大大优于列表的。元组、列表在使用的时候,都是通过下标索引取值的。
下标索引取值不太人性化,如果我知道数据储存在元组里面,但是我不知道它具体储存的下标位置。这个时候找这个元素,还得先把下标找出来,知道下标再去拿,这样很不方便。
字典的话,这方面就比较有优势。数据是存储在字典里面的,只要通过键,就能把值找到。字典相对于元组和列表,有一定的优势和劣势。
命名元组使用的时候可以让元组像字典一样去取值。
例如,有个元组里面保存了3条数据:
创建一个命名元组的话,需要用到Python的一个内置模块fromcollectionsimportnamedtuple
importtimeit这个模块可以用来做性能分析fromcollectionsimportnamedtuplenamedtuple是个函数,创建命名元组可以通过这个函数来创建deffunc():foriinrange(10):print(i)这个对象有个方法叫做timeitrestimeit。Timer(func)。timeit(100)把这个func函数传进去,运行100次,然后返回的是个时间timeit。Timer(func)。timeit(100)中函数func是不需要加引号的,如果是字符串、列表这些需要加引号放进去print(res)res2timeit。timeit(〔1,2,3〕)print(res2)命名元组如果知道里面储存的具体位置,可以通过下标取值。例如tu〔0〕如果我不知道名字存储在哪里,通过下标去取值就不好取了命名元组可以使取值的时候像列表一样取studentinfonamedtuple(infotuple,〔name,age,gender〕)这个函数接收2个参数,第一个参数是创建命名元组的类型的名字;第二个参数的话,传一个列表列表里写创建命名元组的一个命名,例如第一个元素命名为name这个函数调用传了2个参数,返回出来一个对象。这个对象叫做studentinfo通过这个对象studentinfo创建命名元组tustudentinfo(qinghan,18,nv)print(tu)
这个tu就是个命名元组。
studentinfo是通过命名元组这个namedtuple函数创建命名元组类型:namedtuple(infotuple,〔name,age,gender〕)。
然后返回出来一个对象studentinfo
通过studentinfo这个对象传入对应的元组,定义元组的时候就通过这个对象把元素写进去,返回的就是命名元组。三、命名元组有什么特点?
它取值的时候可以像字典一样取值,通过对应的键,找到对应的值。命名元组使用起来更像对象。
这样用:命名元组。name
这样就能找到name所对应的值:importtimeit这个模块可以用来做性能分析fromcollectionsimportnamedtuplenamedtuple是个函数,创建命名元组可以通过这个函数来创建deffunc():foriinrange(10):print(i)这个对象有个方法叫做timeitrestimeit。Timer(func)。timeit(100)把这个func函数传进去,运行100次,然后返回的是个时间timeit。Timer(func)。timeit(100)中函数func是不需要加引号的,如果是字符串、列表这些需要加引号放进去print(res)res2timeit。timeit(〔1,2,3〕)print(res2)命名元组如果知道里面储存的具体位置,可以通过下标取值。例如tu〔0〕如果我不知道名字存储在哪里,通过下标去取值就不好取了命名元组可以使取值的时候像列表一样取studentinfonamedtuple(infotuple,〔name,age,gender〕)这个函数接收2个参数,第一个参数是创建命名元组的类型的名字;第二个参数的话,传一个列表列表里写创建命名元组的一个命名,例如第一个元素命名为name这个函数调用传了2个参数,返回出来一个对象。这个对象叫做studentinfo通过这个对象studentinfo创建命名元组tustudentinfo(qinghan,18,nv)print(tu。name)
设定命名元组类型的时候,它返回的这个对象它里面只包含了传进去的这几个名字。
接下来,要创建命名元组的时候,元素和它一样多,名字和对应的元素的值是一一对应的,不能多,不能少。
否则就会报错:
print(type(tu))看下它的类型
它返回的对象和类型名用的同一个名字。print(type(studentinfo))
importtimeit这个模块可以用来做性能分析fromcollectionsimportnamedtuplenamedtuple是个函数,创建命名元组可以通过这个函数来创建deffunc():foriinrange(10):print(i)这个对象有个方法叫做timeitrestimeit。Timer(func)。timeit(100)把这个func函数传进去,运行100次,然后返回的是个时间timeit。Timer(func)。timeit(100)中函数func是不需要加引号的,如果是字符串、列表这些需要加引号放进去print(res)res2timeit。timeit(〔1,2,3〕)print(res2)命名元组如果知道里面储存的具体位置,可以通过下标取值。例如tu〔0〕如果我不知道名字存储在哪里,通过下标去取值就不好取了命名元组可以使取值的时候像列表一样取设定命名元组类型studentinfo是个类studentinfonamedtuple(studentinfo,〔name,age,gender〕)这个函数接收2个参数,第一个参数是创建命名元组的类型的名字;第二个参数的话,传一个列表列表里写创建命名元组的一个命名,例如第一个元素命名为name这个函数调用传了2个参数,返回出来一个对象。这个对象叫做studentinfo通过这个对象studentinfo创建命名元组tustudentinfo(qinghan,18,nv)print(tu。name)print(type(tu))看下它的类型print(type(studentinfo))因为studentinfo是个类,所以看studentinfo的type就是个type。随便看哪个类都是一样的。