当前位置: 首页 > 后端技术 > Python

#振动小手学Python#列表和元组的那些事【附源码】

时间:2023-03-25 22:13:23 Python

1.列表和元组的那些事1.为什么列表和元组总要放在一起?学好基本用法后,你应该有个基本印象,列表和元组是一个有序的集合,可以放置任何数据类型,也可以作为容器使用。两者最直接的区别就是list的长度不是固定可变的,而tuple的长度是固定不可变的。在很多地方,这种区别被称为动态和静态。这里最常见的错误之一是分配或修改元组的值。错误信息如下。如果发生,你需要知道原因吗?TypeError:'tuple'objectdoesnotsupportitemassignment如何给元组添加数据,我想大家应该比较清楚,就是新建一个元组,将新数据与旧数据拼接,搞定。#梦橡皮擦专用反爬虫评论my_old_tuple=(1,2,"a","b")my_new_tuple=("c","d")my_tuple=my_old_tuple+my_new_tupleprint(my_tuple)基础部分比较多注意,如果元组只有一个元素,必须这样写(1,)。不要错过逗号。如果漏掉了括号中的数据类型,最后会得到该数据类型的数据。1.1列表和元组的切片列表和元组是有序的,切片可以有序切片,而切片是不关心开始和结束的操作,比如下面的代码。my_tuple=my_old_tuple+my_new_tupleprint(my_tuple[1:3])刚刚学习切片的时候,一个比较常见的错误如下。这个错误的原因是[]方括号里面的:写成了另外一个符号。TypeError:tupleindicesmustbeintegersorslice,nottuple1.2负索引,两个列表和切片之间的相互转换都支持负索引值,但是要知道负索引是从-1开始的,为什么呢?为你自己想想。窃窃私语:不是因为只有一个0,两个可以相互转换。转换应用于内置函数列表和元组。在函数学习之后,还有一些内置函数可以应用于列表和元组。这部分是滚雪球的,我们第一次学的时候就已经全部搞定了,很简单的知识点。1.3列表和元组的存储方式运行如下代码,查看运行结果。列表和元组的元素个数是一致的。my_list=["a","b","c"]print(my_list.__sizeof__())my_tuple=("a","b","c")print(my_tuple.__sizeof__())输出存在差异就是对于相同元素数据的列表和元组,系统分配给列表的空间更大。6448第一个知识点是__sizeof__():打印系统分配的空间大小。接下来,让我们对其进行一个基本的测试,看看系统是如何从链表中分配空间的。my_list=[]print("初始化大小",my_list.__sizeof__())my_list.append("a")print("添加1个元素后的大小",my_list.__sizeof__())my_list.append("b")print("添加2个元素后的大小",my_list.__sizeof__())my_list.append("c")print("添加3个元素后的大小",my_list.__sizeof__())my_list.append("d")print("添加4个元素后的大小",my_list.__sizeof__())my_list.append("e")print("添加5个元素后的大小",my_list.__sizeof__())运行结果为:Initializesize40size加1个元素后72大小加2个元素后72大小加3个元素后72大小加4个元素后72大小加5个元素后72大小1041个元素后大小改成72,然后连续加4个元素,分配的大小by系统没有变化,增加了5个元素,增加了32个字节的空间,所以可以得出结论:list会一次增加4个元素的空间,当空间用完后,会继续增加。上面代码的原理:列表本质上是一个动态数组。列表真正存储的数据并不是列表实际存储的数据,而是每个元素在内存中的地址(引用),因为列表存储的是对元素的引用。所以引用占用的内存空间是一样的,都是8个字节,不同类型的数据都可以这样存储。在64位操作系统中,地址占用8个字节。如果您的计算机是32位的,则该地址占用4个字节。只要注意。1.4列表和元组的应用场景简单来说,元组用于元素内容固定的数据,列表用于可变数据。如果想更容易记住,可以直接录下来,好像只需要2、3个一样。对于元素,使用tuple,对于更多元素,使用namedtuple,它是一个函数。使用namedtuple需要先导入。fromcollectionsimportnamedtuplehelp(namedtuple)函数原型如下:namedtuple(typename,field_names,*,rename=False,defaults=None,module=None)#返回一个新的具有命名字段的元组子类。先写一段测试代码:fromcollectionsimportnamedtuplePoint=namedtuple('Point',['x','y'])p=Point(10,20)print(p.x)print(p.y)前两个参数需要简单了解一下。typename:字符串类型的参数。这个参数很难理解。贴出官方解释。namedtuple()将根据这个类型名创建一个子类类名并返回它。比如上面测试代码中的Point就创建好了。类名是Point,第二个参数是未来的类属性。field_names:用于命名创建的元组的每个元素,可以传入列表或元组,如['a','b'],(a,b),也可以传入'ab'或'a,b'这是一个由逗号或空格分隔的字符串。上面如果想看类构建的过程,可以加参数verbose,不过官网上也有说明这个参数,有些版本不支持,Python3.7以后没有这个属性。在3.6版中更改:verbose和rename参数变为仅关键字参数。在3.6版中更改:添加了模块参数。在3.7版中更改:删除了verbose参数和_source属性。在3.7版中更改:添加了defaults参数和_field_defaults属性。是否使用list()或[]来初始化一个空列表。您可以使用以下代码来测试此内容的效率。importtimeita=timeit.timeit('a=list()',number=10000000)b=timeit.timeit('a=[]',number=10000000)print(a)print(b)结果:1.66348190.5888171999999998结论是[]更快,因为list()是函数调用,效率肯定低。通过以上函数,你还可以测试相同的元素在初始化列表或元组时是否更高效。importtimeita=timeit.timeit('a=("a","b","c")',number=10000)b=timeit.timeit('b=["a","b","c"]',number=10000)print(a)print(b)结果如下:#初始化元组0.0005571000000000048#初始化列表0.0020220999999999991.5本篇博客总结本篇博客重点回顾了列表和元组的一些基本内容,并进行了探索列表和元组在系统分配上的区别,为大家扩展了一个namedtuple函数,最后可以扩展了解timeit模块。