列表
本质
列表在底层是一个动态顺序表结构(连续内存),使用分离法,元素外置的方法存储:
- 元素值使用随机内存地址保存(因为列表需要能保存不同基础类型的元素,所以需使用元素外置)
- 顺序表真正存储的是指向元素值的地址
- 动态扩容的策略(其中一种 加倍扩充):
- 初次申请空列表 会开辟8个元素的容量大小
- 当列表扩充空间不够时,则会以4倍基础大小重新申请新的内存,再将原存储区的数据搬到新的内存地址,然后释放原存储区内存;
- 当容量超过50000,则改为1倍来扩充
常规操作
列表组合 list1+list2 返回新的列表list3
列表的重复: list1*3 ,重复打印三次,返回一个新的列表
列表的截取 list1[:] list1[::-1] :列表翻转
1 li = [1,2,3,4,5] 2 print(li[:3:-1]) 3 >>[5] 4 print(li[1:3:-1]) 5 >>[] 6 print(a[2:3:-1]) 7 >>[] 8 step为-1,只会倒着从后面开始取
list.append(x) 原列表末尾追加新元素,函数返回为空
list.extend(iterable) iterable: 可迭代对象; 将可迭代对象中的元素取出,分开加入列表
list.insert(index,x) 在指定的下标处插入元素,原来该位置的元素往后移
list.pop(index) 删除指定下标的元素,若下标不存在则报错 index默认为-1,即默认删除最后一个, 函数返回删除的那个元素.
list.remove(x) 移除列表中某个元素的第一个匹配结果, 若匹配不到则报错,函数返回为空
del list 删除列表
list.clear() 清空列表中的所有元素,列表还存在
list.index(x,start,stop) 从指定范围的列表中找出x第一匹配的索引值,若不指定范围,则是整个列表
list.count(x) 统计列表中x元素出现的次数
len(list) 获取列表长度
max(list) 返回列表中最大元素 min(list) 返回最小
list.reverse() 列表倒叙,翻转
list.sort(reverse=False) 对列表中的元素进行排序,默认升序,若reverse=True,则为降序
列表切片
列表切片后得到的还是一个列表,占用新的内存地址
切片只是浅拷贝:当取出切片的结果时,它是一个独立对象,但它拷贝的是原列表中元素的引用,所以,当存在变长对象的元素时,对其修改会影响源列表
列表切片的赋值:可以直接对切片进行赋值,从而修改原列表,但赋值对象只能是可迭代对象,它会先删除原列表中切片的元素,再将可迭代对象拆散插入到切片的位置
li = [1,2,3,6,5,4] li[2:4] = [100,200,300] print(li) # 结果>>> [1, 2, 100, 200, 300, 5, 4]
列表拷贝
赋值拷贝:
为引用拷贝 引用同一个列表,地址一样
list1 = [1,2,3]
list2=list2
浅拷贝:
list2=list1.copy()
为一维内存拷贝,开辟一块新的内存空间
若出现二维列表时,由于在一维列表中储存的是列表的地址
所以当二维列表的时候,又是操作的同一块区域
深拷贝:
import copy
list2=copy.deepcopy(list1)
深拷贝是一个完全的内存拷贝,将list1中的所有元素拷贝了一份存入新地址,不会出现同时操作同一块内存的情况.
列表枚举函数 :enumerate(列表)
enumerate(obj,start) obj 可迭代对象,start 下标起始位置 默认为0
for index, x in enumerate(list1) 同时遍历下标与元素
print(index,x)
元组
修改元组
元组是不可修改的,存储到元组中的列表其实是存储的是列表的地址,这个地址无法修改,但是列表里的元素可以进行修改,而列表地址是不变的
对元组的元素进行排序
元组是不可改变的,但能对其元素排序生成新的元组
sorted(t) # 返回排序后的新元组
对多个元组进行排序
t = [(3,5),(1,4),(6,3),(3,1)] t.sort() print(t) # [(1, 4), (3, 1), (3, 5), (6, 3)]