列表篇——深,浅拷贝,删除,反转,排序
列表索引
- 索引(下标)
- 正索引:从左到右,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
- shadow copy 返回一个新列表
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], 不会对另一个列表产生影响 -
为了方便理解我简单做了图如下: