列表辅助功能
- 一、列表运算
- 1、列表拼接
- 2、列表迭复
- 3、列表查询
- 二、内置函数
- 1、列表乱序
- 2、测试真值
- 3、最大 / 最小值
- 4、元素和 / 元素个数
- 5、压缩(zip操作)
- 6、枚举(enumerate对象)
- 三、列表推导式
- 1、嵌套列表平铺
- 2、过滤列表元素
- 3、同时遍历多列表
- 4、矩阵转置
- 四、切片
- 1、列表元素 - CRUD
- ① C(Create) - 增
- ② R(Retrieve) - 查
- ③ U(Update) - 改
- ④ D(Delete) - 删
- 2、列表拷贝
- 五、序列解包
本文使用 Python 版本为 3.9.5
列表的特点:列表是包含若干元素的有序连续内存空间,当增加和删除元素时,列表对象自动进行内存的扩展、收缩,保证相邻元素之间没有缝隙。但由于自动扩展、收缩操作会产生额外的开销,应尽量从列表尾部追加、删除元素。与元组一样,列表也支持双向索引。
与其他计算机编程语言相比,Python 并没有数组的概念,使用列表取代了数组,并为它赋予了更加强大的功能。
列表 / 元组 区别:
① 元组不可变,列表可变。
② 元组访问速度快,列表访问速度相对较慢。
一、列表运算
列表运算使得 Python 无需调用方法就可以轻易的完成列表与列表之间的操作,表面上无需调用方法,大大简化了使用者的操作,使其更加的人性化,便于我们理解。
1、列表拼接
x = [1,2,3];
#连接两个列表
x = x + [4]; #x = [1,2,3,4],拼接列表不是原地操作,地址发生改变
#向列表中追加元素
x+=[5]; #x = [1,2,3,4,5],追加元素为原地操作,地址不发生改变
2、列表迭复
#创建列表
x = [1,2,3];
#列表迭复
x = x * 2; #x = [1,2,3,1,2,3],这种操作创建了新的列表,非原地操作,地址发生改变
#列表迭复
x *= 2; #x = [1,2,3,1,2,3],这种操作为原地操作,地址不发生改变
3、列表查询
3 in [1,2,3] #True,包含元素3
3 in [1,2,4] #False,不含有元素3
6 in [1,2,'6'] #False,不含有相同类型的元素6
二、内置函数
Python 提供了大量的内置函数,这些函数针对的对象不同,有些函数对字符串等其他对象也有效(如len),通用的操作使得我们的操作更加便捷、易懂。
1、列表乱序
#创建列表
x = list(range(10)) #x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#导入random包
import random
#调用shuffle乱序方法,列表内元素顺序发生改变
random.shuffle(x) #x = [3, 6, 2, 0, 4, 8, 9, 1, 5, 7]
#再次调用shuffle乱序方法,列表内元素顺序发生改变
random.shuffle(x) #x = [7, 0, 4, 5, 8, 1, 3, 2, 9, 6]
#创建不同类型对象并存的列表
y = ['1', 'a', 9, [0]]
#调用shuffle乱序方法,列表内元素顺序发生改变
random.shuffle(y) #y = [[0], 'a', 9, '1']
2、测试真值
我们知道,在 Python 中,True 等同于数值 1、字符‘1’,False 等同于数值 0,测试元素中是否有等价于 True 的元素,可以称之为:“测试真值”,这对于仅有True / False 或 1 / 0 的数组有很大意义。
#创建列表
x = [0,1,2,3,4]
y = [1,'1',True]
#1、测试所有元素是否都等价于True(任意∀)
#测试
all(x) #False
all(y) #True
#2、测试是否存在元素等价于True(存在∃)
#测试
any(x) #True
any(y) #True
3、最大 / 最小值
#创建列表,将迭代对象转化为列表
x = list(range(15)) #x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
#返回最大值
max(x) #结果:14
#按规则返回最大值
max(x,key=int) #等同于“max(x)”,结果:14
max(x,key=str) #结果:9
#返回最小值
min(x) #结果:0
4、元素和 / 元素个数
#创建列表,将迭代对象转化为列表
x = list(range(15)) #x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
#列表元素和
sum(x) #结果:105
#列表元素个数
len(x) #结果:15
5、压缩(zip操作)
#压缩列表、迭代对象
list(zip(['a','c','b'],range(3))) #[('a', 0), ('c', 1), ('b', 2)]
#压缩双列表
list(zip(['a','b'],[0,1])) #[('a', 0), ('b', 1)]
#压缩操作,长度不等,长度取最小
list(zip(['a','c','b'],range(2))) #[('a', 0), ('c', 1)]
list(zip(['a','b'],[0,1,3])) #[('a', 0), ('b', 1)]
6、枚举(enumerate对象)
#创建列表,将迭代对象转化为列表
x = list(range(10)) #x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#enumerate对象可以转换为列表、元组、集合
#枚举列表元素
e = enumerate(x) #<enumerate object at 0x0000019E62BBC638>
list(e) #[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9)]
#枚举列表元素
e = enumerate(x) #<enumerate object at 0x0000019E62BBC639>
tuple(e) #((0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9))
#枚举列表元素
e = enumerate(x) #<enumerate object at 0x0000019E62BBC640>
set(e) #{(0, 0), (3, 3), (5, 5), (6, 6), (4, 4), (7, 7), (9, 9), (8, 8), (2, 2), (1, 1)}
三、列表推导式
列表推导式简化了我们的操作,增强了我们代码的可读性,减少了在外层直接使用循环的次数,使得我们对列表的操作更为便捷。
1、嵌套列表平铺
#创建嵌套列表
arr = [[1,2,3],[4,5,6],[7,8,9]]
#平铺arr
a = [e for ar in arr for e in ar] #a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
#ar代表列表内的子列表,剖析该语句[e|for ar in arr|for e in ar]('|'为分隔符,没有实际含义),按步骤先取出子列表,再取出子列表元素,最终将结果赋予a变量。
2、过滤列表元素
#创建列表
x = [2,3,5,6,3,21,3.4,8,11]
#过滤元素
l = [i for i in x if i > 7] #l = [21, 8, 11]
#剖析语句[i|for i in x|if i > 7]('|'为分隔符,没有实际含义)
3、同时遍历多列表
x = [1,2,3]
y = [2,3,4]
r = [(i , j) for i in x for j in y if(i < j)]
#r = [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
#剖析语句[(i , j)|for i in x|for j in y|if(i < j)]('|'为分隔符,没有实际含义)
4、矩阵转置
#创建矩阵(二维列表)
matrix = [[1,2,3],[4,5,6],[7,8,9]]
#矩阵转置
grid = [[row[i] for row in matrix] for i in range(len(matrix))]
#剖析语句
#[ [row[i] 取出元素,重新填入
# for row in matrix] 按每个子列表的同索引依次取值,注入新的子列表中(等同于嵌套for循环内层循环)
# for i in range(len(matrix)) ] 取出行值(等同于嵌套for循环外层循环)
#该操作,等同于嵌套for循环,内层循环重构子列表,外层循环组合新子列表为新矩阵
#
#matrix = [[1,2,3], grid = [[1,4,7],
# [4,5,6], [2,5,8],
# [7,8,9]] [3,6,9]]
#综上,矩阵完成转置
四、切片
一个完整的切片表达式包含两个“:”,用于分隔三个参数(start_index、end_index、step),当只有一个“:”时,默认第三个参数step=1。
#步长及其前面的冒号可以省略,其余均不能省略
L[start_index:end_index:step]
列表名[起始:终止:步长]
start_index 代表起始索引(可以是正向索引,也可以是反向索引)
end_index 代表终止索引(可以是正向索引,也可以是反向索引)
step 正负数均可,其绝对值大小决定了切取数据时的“步长”,而正负号决定了“切取方向”。
1、列表元素 - CRUD
① C(Create) - 增
#创建列表
x = [5,6,9,8]
#列表尾插
#灵活使用内置函数len(),为列表追加元素,元素数量不定,但形式须为列表
x[len(x):] = [9] #x = [5,6,9,8,9]
#列表头插
x[:0] = [7,7] #x = [7, 7, 5, 6, 9, 8, 9]
#列表间插
#在索引(下标)为3的地方插入元素,元素数量不定,但形式须为列表
x[3:3] = [1,1,1] #x = [7, 7, 5, 1, 1, 1, 6, 9, 8, 9]
② R(Retrieve) - 查
#创建列表
x = list(range(5,11)) #x = [5, 6, 7, 8, 9, 10]
#显示所有元素
x[::] #等同于x[:],结果:[5, 6, 7, 8, 9, 10]
#获取元素逆序列表
x[::-1] #结果:[10, 9, 8, 7, 6, 5]
#获取偶数位元素列表
x[::2] #结果:[5, 7, 9]
#获取奇数位元素列表
x[1::2] #结果:[6, 8, 10]
#获取中间元素列表:截断
x[2:4] #结果:[7, 8]
#切片起始位置超出长度,返回空列表
x[20:] #结果:[]
#反向切片:截断 + 逆序
x[-1:2:-1] #结果:[10, 9, 8]
#正向切片:截断 + 正序
x[0:-2] #结果:[5, 6, 7, 8]
③ U(Update) - 改
#创建列表
x = [0,1,2,3,4]
#范围修改
#替换元素
x[:3] = ['a','b','c'] #x = ['a', 'b', 'c', 3, 4]
#替换+追加元素
x[3:] = ['d','e','f'] #x = ['a', 'b', 'c', 'd', 'e', 'f']
#间隔修改
#按偶数索引修改
x[1::2] = [1]*3 #x = ['a', 1, 'c', 1, 'e', 1]
x[1::2] = [1,2,3] #x = ['a', 1, 'c', 2, 'e', 3]
#按奇数索引修改
x[::2] = [9]*3 #x = [9, 1, 9, 2, 9, 3]
④ D(Delete) - 删
#创建列表
x = [0,1,2,3,4]
#指定(范围)删除
del x[2:3] #x = [0, 1, 3, 4]
#间隔删除
del x[::2] #x = [1, 4]
2、列表拷贝
使用切片功能的拷贝为浅拷贝,两个对象的地址不同,不是同一地址,但其中相同的值,在内存中仅有一份。
#创建列表
x = [0,1,2,3]
#浅拷贝
y = [::]
#查看对象地址
id(y) #结果:2111194456968,后三位968
id(x) #结果:2111194456648,后三位648
#修改y的部分元素值
y[0] = 'a' #y = ['a', 1, 2, 3],x = [0, 1, 2, 3]
#当列表嵌套时,或包含其他可变序列时
a = [[0],[1],[2]]
#浅复制
b = a[::]
#为b的第二项列表追加元素
b[1].append(5) #此时,a 与 b 同时发生变化:b = [[0], [1, 5], [2]],a = [[0], [1, 5], [2]]
当列表项为用户自定义类时,情况会变得更加复杂,解决方法是使用标准库中的deepcopy()函数。
#创建列表
a = [[0],[1],[2]]
#导入标准库copy
import copy
#浅拷贝(第一个copy为库名,第二个copy为方法名)
b = copy.copy(a) #b = [[0],[1],[2]]
#深拷贝
c = copy.deepcopy(a) #c = [[0],[1],[2]]
#为b第二项的列表追加元素
b[1].append(5) #a = [[0],[1,5],[2]],b = [[0],[1,5],[2]],c = [[0],[1],[2]]
此时各列表内元素为:a = [[0],[1,5],[2]],b = [[0],[1,5],[2]],c = [[0],[1],[2]],可以看到 列表c 完成深拷贝。
五、序列解包
序列解包(Sequence Unpacking)简化了代码,提高了程序的可读性,使得代码的书写更加流畅。
- 序列解包支持 列表、字典、字符串、enumerate对象、filter对象、zip对象等
#创建列表
a = [1,2,3]
#序列解包
b,c,d = a #b = 1, c = 2, d = 3
#字符串序列解包
s = 'ABC'
b,c,d = s #b = 'A', c = 'B', d = 'C'