列表篇——深,浅拷贝,删除,反转,排序

列表索引

  • 索引(下标)
  • 正索引:从左到右,0开始,为列表内元素编号
  • 负索引:从右到左,从-1开始
  • 正负索引不可超界,否则报错IndexError
  • 为了方便理解可认为列表从左到右排列,左为下界限,右为上界限

  • 列表通过索引访问
    • list [index] , index就是索引,使用中括号访问

例如:

l1 = [A,B,C,D]
  • 那么列表l1中A,B,C,D元素
    • 正索引依次为:0,1,2,3
    • 负索引依次为:-4,-3,-2,-1

列表查询

  • index (value,[start,[stop]]
    • 通过值value,从指定区间查找列表内的元素是否匹配
    • 匹配第一个就立即返回索引
    • 匹配不到,抛异常ValueError
  • count(value)
    • 返回列表匹配value次数
  • 时间复杂度
    • index和count方法都是O(n)
    • O(n)随着列表数据规模增大效率下降
    • 时间复杂度为O(1)是更为高效的
  • len()
    • 返回列表元素长度(个数)
    • 时间复杂度位O(1)

列表元素修改

  • 索引访问修改
    • list[index] = value
    • 注意索引不要超界

列表元素增加,插入

  • append(object) -> None
    • 列表尾部追加元素,返回None
    • 返回None意味着没有新列表产生,就地修改
    • 时间复杂度为O(1)
  • insert(index,object)->None
    • 在指定索引index插入object
    • 返回None意味着没有新列表产生,就地修改
    • 时间复杂度为O(n)
    • 索引超过上下界
      • 超过上界尾部追加(相当于尾部追加)
      • 超过下界头部追加(影响极大,后面数据全部右移)

列表元素扩展

  • extend(iteratable) -> None
    • 将可迭代对象元素追加进来,返回None
    • 就地修改
  • + -> list
    • 连接操作,将两个列表连接起来
    • 产生新列表,原列表不变
    • 本质调用魔术方法_add_()方法
    • 与extand相比产生新列表,需要申请新的内存空间,更占用内存
  • * -> list
    • 重复操作,将本列表元素重复n次,返回新列表

列表删除元素

  • remove(value) -> None
    • 从左到右查找第一个匹配value值,移除该元素,返回None
    • 就地修改
    • 会引起数据移动(列表最后一个数据除外),O(n)
  • pop([index]) -> item
    • 不指定索引,从列表尾部弹出一个元素
    • 指定索引index,从索引处弹出一个元素,索引超界抛错IndexError
    • 指定索引效率低,时间复杂度高O(n)
    • 不置顶索引效率高,时间复杂度低O(1)
    • 不指定索引情况下与append配合使用效率较高
  • clear() -> None
    • 清除列表所有元素,剩下一个空列表
    • 此处并非马上从内存删除列表内所有元素,而是把各元素引用计数都 -1 ,此列表为空,长度为0,删除操作由GC完成

列表其他操作

  • reverse() -> None
    • 将列表元素反转,返回None
    • 就地修改
  • sort(key=None,reverse=False) -> None
    • 对列表元素排序,就地修改,默认升序
    • reverse为Ture,反转,降序
    • key是一个函数,指定key如何排序
      • lst.sort(key=function)
  • in
    • [3,5] in [1,2,[3,5],6]
    • for x in [1,2,3,6,7]

列表复制

  • copy() -> list
    • shadow copy 返回一个新列表
      • 影子拷贝,也叫浅拷贝,遇到引用类型只是复制一个引用而已
    • 深拷贝
      • copy模块提供了deepcopy
   import copy 


举个栗子:

    Lst1=[1,[a,b,c],3]
    Lst2=Lst1.copy()
    Lst2=[1,[a,b,c],3]
  • 对于浅拷贝:
    如果我们修改 Lst1[2]=9
    那么列表 Lst1=[1,[a,b,c],9]
    列表 Lst2=[1,[a,b,c],3]
    修改 Lst1[0] 也是一样的,列表Lst2 不会受到影响,同理修改 Lst2[0] 和 Lst2[2] 也不会影响列表Lst1
    不过,如果我们修改 Lst1[1]
    这时列表Lst1和列表Lst2都会受到影响
  • 对于深拷贝:
    import.copy
    Lst1=[1,[a,b,c],3]
    Lst2=copy.deepcopy(Lst1)
    Lst2=[1,[a,b,c],3]
  • 如果我们修改 Lst1[2]=9
    那么列表 Lst1=[1,[a,b,c],9]
    不过列表 Lst2=[1,[a,b,c],3]
    修改 Lst1[0] 也是一样的,列表Lst2 不会受到影响
    如果我们修改 Lst1[1] ,列表 Lst1 会变化 ,列表 Lst2 不会受到 Lst1 的影响
  • 总结
    1.无论深浅拷贝,修改列表内‘简单类型’元素,如1,3,都不会对拷贝后的列表产生影响
    2.对于浅拷贝,修改列表内‘复杂类型’元素,如 [a,b,c], 会对拷贝前后两列表产生影响
    3.对于深拷贝,修改列表内‘复杂类型’元素,如 [a,b,c], 不会对另一个列表产生影响
  • 为了方便理解我简单做了图如下:

在这里插入图片描述
在这里插入图片描述

推荐使用索引操作,非索引操作尽量不用或少用

猜你喜欢

转载自blog.csdn.net/Bughuu/article/details/88869179