【Python基础】强大的列表:内置函数利用、列表表达式、切片


本文使用 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'
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值