第3.3节 强大的Python列表

一、 列表切片操作补充

  1. 列表切片支持所有序列切片的方法,以倒序切片和步长大于1的情况再举例验证一下:
    在这里插入图片描述
    l=[1,2,3,4,5]
    l[::2] #结果[1, 3, 5]
    l[-1::2] #结果[5]
    l[-1::-2] #结果[5, 3, 1]
    其他序列已有的切片方法在列表中同样适用,这里就不举例说明了。

  2. 通过切片赋值:当给切片赋值为与切片个数相同的元素数量的列表时,实际上就是将切片指定的元素替换为新列表的内容。举例:
    在这里插入图片描述
    c=[1,2,3,‘a1178’,‘b210’,‘c3112’]
    c[2:5]=[100,200,‘abcdefg’] #执行结果为c=[1, 2, 100, 200, ‘abcdefg’, ‘c3112’]

  3. 通过切片插入给定列表中的值到原列表中指定位置,具体位置通过切片起始索引指定,此时两个索引值应该相等
    在这里插入图片描述
    c=[1,2,3,‘a1178’,‘b210’,‘c3112’]
    c[2:2]=[‘ABC’,‘123’,‘E456’] #执行完毕后, c=[1, 2, ‘ABC’, ‘123’, ‘E456’, 3, ‘a1178’, ‘b210’, ‘c3112’]

  4. 通过切片更新和同时插入元素:上面两点讲了切片元素替换和插入,如果赋值语句右边的列表长度长于切片的起始位置包含的元素个数,是否会导致切片段的元素被替换,多余的被插入?
    在这里插入图片描述
    c=[1,2,3,‘a1178’,‘b210’,‘c3112’]
    c[2:4]=[100,200,300,400] # c =[1, 2, 100, 200, 300, 400, ‘b210’, ‘c3112’],确实是切片部分被替换,多出切片部分的新元素插入

  5. 如果列表元素个数少于切片包含的元素个数呢?我们来看实际例子:
    在这里插入图片描述
    c=[1,2,3,‘a1178’,‘b210’,‘c3112’]
    c[2:5]=[100,200] #c=[1, 2, 100, 200, ‘c3112’],切片超过赋值列表的部分被删除了

  6. 删除列表的元素:通过上面的例子,我们发现切片还可以删除元素,那整个列表清空也可以通过切片操作,其语法是c[:]=[],类似于clear的效果。

  7. 如果切片时带步长不等于1又会什么效果?具体在这里不讲解了,举例如下:
    在这里插入图片描述

    c=[1,2,3,‘a1178’,‘b210’,‘c3112’]
    c[::2]=[] #报错,3个元素的切片不能赋值为空序列
    c[::2]=[‘A’,‘B’,‘C’] #正常执行,替换1、3、5三个元素,结果[‘A’, 2, ‘B’, ‘a1178’, ‘C’, ‘c3112’],很神奇吧?
    c[::2]=[‘A’,‘B’,‘C’,‘D’,‘E’]#报错,3个元素的切片不能赋值为大小为5的序列
    c[::2]=[‘A1’,‘B1’]#报错,3个元素的切片不能赋值为大小为2的序列

从以上试验可以看出,只有当用于替换的列表的元素个数与被替换的切片元素个数相等时才会允许步长不等于1切片赋值操作

以上详细介绍了列表的切片的进一步操作,还有其他的操作方法,如怎么把extend用切片方式实现,怎么用切片复制一个列表,大家可以自己想想和试验一下,在此不再详细介绍。总体来说,切片让序列和列表很神奇很灵活,但在本阶段知识下的老猿认为实际在程序开发中利用起来的场景应该不多,不知道随着进一步的学习是否有变化。

二、 列表的其他操作

  1. 序列的拼接、相乘在列表中同样支持,举例如下:
    在这里插入图片描述
    l1=l+l #执行结果 l1为[1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
    l2=l*3 #执行结果 l2为[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

  2. in这个方法在序列中就存在,前面介绍序列时没有介绍,在这以列表补充说明一下。
    语法:元素 in 列表,返回True或False的布尔值
    在这里插入图片描述
    ls = [‘abc’,‘a1’,‘b2’,‘c3’]
    ‘abc’ in ls #返回结果True
    字符串的使用方法类似,字典中使用有些不同,在字典章节再详细介绍。

  3. max、min、len在列表中同样可以使用,但max、min要求列表的元素必须是纯数字或纯字符串的,不能支持数字和字符串的混合,但支持列表的元素还是列表,且每个子列表的元素都是数字或者都是字符串(多个子列表的元素类型必须相同),看看下面的例子
    在这里插入图片描述

    n=[1,2,3]
    c=[‘a’,‘ba’,‘c1’]
    max(n),max© #执行结果(3, ‘c1’)
    l = n+c #执行结果[1, 2, 3, ‘a’, ‘ba’, ‘c1’]
    max(l)报错:
    Traceback (most recent call last):
    File “<pyshell#6>”, line 1, in
    max(l)
    TypeError: ‘>’ not supported between instances of ‘str’ and ‘int’
    l=[n]+[n] #执行结果 l=[[1, 2, 3], [1, 2, 3]],注意列表元素还是列表
    max(l) #执行结果为[1, 2, 3]
    l=[c]+[c] #执行结果为 l=[[‘a’, ‘ba’, ‘c1’], [‘a’, ‘ba’, ‘c1’]]
    max(l) #执行结果为[‘a’, ‘ba’, ‘c1’]
    l=[n]+[c]#执行结果为l=[[1, 2, 3],[‘a’, ‘ba’, ‘c1’]]
    max(l)报错:
    Traceback (most recent call last):
    File “<pyshell#15>”, line 1, in
    max(l)
    TypeError: ‘>’ not supported between instances of ‘str’ and ‘int’

  4. count方法是列表的方法,用于计算指定元素在列表中出现的次数,该方法还可以用于字符串和元组,但不能用于字典类型;

  5. reverse是列表方法,该方法用于将列表中的元素反序排列,并不返回任何值,但并不表示列表中的元素是按降序排列。
    l=[1,3,5,7,6]
    l.reverse() #执行结果l= [6, 7, 5, 3, 1]

  6. sort是列表方法,可以对列表元素进行排序(包括升序和降序),如果要降序排列,需要指定reverse=True,该方法并不返回任何值。
    l=[1,3,5,7,6]
    l.sort() #执行结果l=[1, 3, 5, 6, 7]
    l.sort(reverse=1) #执行结果l=[7, 6, 5, 3, 1]

  7. sort列表方法还可以指定排序的方法,缺省是按字母顺序,也可以按指定处理方法处理的结果来比较,实际上就是将列表的元素通过一个函数进行hash得到的键值进行比较,具体函数通过参数key来指定,如指定len函数作为处理方法,则是将所有列表元素计算长度后,再按长度进行排序。如:
    在这里插入图片描述

    s = [‘123’,‘abc’,‘1234’,‘abcd’,‘01234’,‘ABC’]
    s.sort(key=len) #执行结果s=[‘123’, ‘abc’, ‘ABC’, ‘1234’, ‘abcd’, ‘01234’]

  8. 函数sorted, 函数的参数可以是任何序列,返回一个排序的列表,参数对应的序列没有变化,与列表方法sort相同,可以指定reverse来确认是升序还是降序。如:

    sorted(l,reverse=True)
    s =‘1231234’
    sorted(s) #返回列表[‘1’, ‘1’, ‘2’, ‘2’, ‘3’, ‘3’, ‘4’],s保持不变

三、 列表的复制
列表的复制涉及内容比较多,因此单列一个段,是将一个列表变量的元素复制到一个新列表中,但两个列表不是同一个对象。先介绍方法:

  1. 用copy方法,语法为:新列表=老列表.copy();

  2. 用切片方法,语法为:新列表=老列表[:];

  3. 用list方法,语法为:新列表=list(老列表).
    注意,以上的复制方法都是浅复制,什么是浅复制?就是复制时,只是完全复制了第一层元素,但第一层元素如果有嵌套的对象(如列表、元组、字典等)时,其指向的下一次对象只是复制了指向,被没有复制内容。下面来看案例:
    在这里插入图片描述

    l=[‘abc’,[1,2,3]]
    l1,l2,l3,l4=l,l.copy(),l[:],list(l) #执行后4个新列表值完全与l一致,别忘了前面第三节(第二章 Python编程基础知识)介绍的“一次给多个变量赋值”操作方法。
    l1,l2,l3,l4 #显示4个列表内容,都是([‘abc’, [1, 2, 3]]
    l is l1 #判断两个对象是否是一个对象,结果为True
    l is l2 #结果为False
    l is l3 #结果为False
    l is l4 #结果为False

    l[0]=‘ABCD’ #修改列表l的第一个元素值
    l[1][0]=100 #修改列表第二个元素嵌套的子列表的第一个元素的值

    l #经过修改后l的值变为[‘ABCD’, [100, 2, 3]]
    l1,l2,l3,l4 #显示4个列表内容,分别是([‘ABCD’, [100, 2, 3]], [‘abc’, [100, 2, 3]], [‘abc’, [100, 2, 3]], [‘abc’, [100, 2, 3]])

从上述执行结果可以看出,由于l和l1是同一对象,对l的所有赋值都会反映到l1,而l2、l3、l4都是浅复制,因此对于l字符串元素的修改都不会影响到它们,但对嵌套子列表的修改会影响到这三个。
关于浅复制,有点类似于c语言的指针数组,浅复制只是将原数组的指向地址复制了一份到新数组,但复制的数组与原数组都存储了各个指针的指向地址,但指针指向内容发生变化时,原始数组指向和新数组指向地址没变,但该地址存储的内容发生了变化,新老数组都可以访问到新的内容。
有浅复制就有深度复制,具体内容后面再讲。

本节继上节之后,对列表的操作方法进一步进行了讲解,列表的功能很强大,大家多练习一下。在这里特别说明一下,老猿所说的方法都是指某类对象的操作方法,属于对象或类所有,函数则是不属于对象和类的通用函数。

老猿Python系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。该系列文章同步发表于:
http://blog.sina.com.cn/learnpython
http://laoyuanpython.lofter.com/
https://me.csdn.net/LaoYuanPython
欢迎大家批评指正,谢谢大家关注!

posted @ 2019-04-15 18:49  老猿学Python  阅读(99)  评论(0编辑  收藏  举报