文章目录
python之List操作(上)
1 列表创建
1) 列表普通创建
使用简单的方式创建列表
推荐写法: 基本语法[]创建
# 创建一个空列表
a = []
# 创建列表
a = [1, 2, 3, 'a', 'b']
# 创建重复列表
a = [1, 2, 3]
b = a * 5 # 结果:b = [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
推荐写法: 使用Python3的标准库,内置函数list()
- range([start,] end [,step])函数可以方便的创建整数列表
- start参数:可选表示起始数字。默认是0
- end参数:必选,表示结尾数字
- step参数:可选,表示步长,默认为1
# 创建空列表
a = list() # 结果:a = []
# 创建字符串列表
a = list('test123') # 结果:a = ['t', 'e', 's', 't', '1', '2', '3']
# 创建整数列表
a = list(range(3, 15, 2)) # 结果:a = [3, 5, 7, 9, 11, 13]
2) 按照推导式创建列表
按照一定的推导式创建有规律的列表
推荐写法: 使用推导式创建列表
# 循环创建多个元素
a = [x * 2 for x in range(5)] # 结果:a = [0, 2, 4, 6, 8]
# 通过if进行条件过滤
a = [x * 2 for x in range(100) if x % 9 == 0] # 结果:a = [0, 18, 36, 54, 72, 90, 108, 126,144, 162, 180, 198]
2. 列表复制
1) 列表浅拷贝
在某些场景下,需要复制当前列表去做一些处理
推荐写法: 使用Python3的标准库,内置函数copy以及copy模块的copy()函数
- 将复制列表关联到原始列表的副本
- 当拷贝的变量包含子对象时,为了节省空间,浅拷贝只会拷贝当前对象,不会拷贝子对象
- 更新复制列表的子对象会同时更新原始列表
a = [1, 2, 3]
# 当copy的对象不包含子对象时
res = a.copy() # 结果:res = [1, 2, 3]
res[1] = 4 # 结果:res = [1, 4, 3]
print(a) # 结果:a = [1, 2, 3]
b = [1, 2, [1, 2, 3]]
# 当copy的对象包含子对象时
res1 = b.copy() # 结果:res1 = [1, 2, [1, 2, 3]]
res1[2][1] = 4 # 结果:res1 = [1, 2, [1, 4, 3]]
print(b) # 结果:b = [1, 2, [1, 4, 3]]
推荐写法: 使用Python3的标准库,copy模块的copy()函数
- 需要导入copy模块
- 将复制列表关联到原始列表的副本
- 当拷贝的变量包含子对象时,为了节省空间,浅拷贝只会拷贝当前对象,不会拷贝子对象
- 更新复制列表的子对象会同时更新原始列表
import copy
a = [1, 2, 3]
# 当copy的对象不包含子对象时
res = copy.copy(a) # 结果:res = [1, 2, 3]
res[1] = 4 # 结果:res = [1, 4, 3]
print(a) # 结果:a = [1, 2, 3]
b = [1, 2, [1, 2, 3]]
# 当copy的对象包含子对象时
res1 = copy.copy(b) # 结果:res1 = [1, 2, [1, 2, 3]]
res1[2][1] = 4 # 结果:res1 = [1, 2, [1, 4, 3]]
print(b) # 结果:b = [1, 2, [1, 4, 3]]
一般写法: 使用切片方式复制
- 将复制列表关联到原始列表的副本
- 当拷贝的变量包含子对象时,为了节省空间,浅拷贝只会拷贝当前对象,不会拷贝子对象
- 更新复制列表的子对象会同时更新原始列表
a = [1, 2, 3]
# 当copy的对象不包含子对象时
res = a[:] # 结果:res = [1, 2, 3]
res[1] = 4 # 结果:res = [1, 4, 3]
print(a) # 结果:a = [1, 2, 3]
b = [1, 2, [1, 2, 3]]
# 当copy的对象包含子对象时
res1 = b[:] # 结果:res1 = [1, 2, [1, 2, 3]]
res1[2][1] = 4 # 结果:res1 = [1, 2, [1, 4, 3]]
print(b) # 结果:b = [1, 2, [1, 4, 3]]
一般写法: 使用Python3的标准库,内置函数list()
- 将复制列表关联到原始列表的副本
- 当拷贝的变量包含子对象时,为了节省空间,浅拷贝只会拷贝当前对象,不会拷贝子对象
- 更新复制列表的子对象会同时更新原始列表
a = [1, 2, 3]
# 当copy的对象不包含子对象时
res = list(a) # 结果:res = [1, 2, 3]
res[1] = 4 # 结果:res = [1, 4, 3]
print(a) # 结果:a = [1, 2, 3]
b = [1, 2, [1, 2, 3]]
# 当copy的对象包含子对象时
res1 = list(b) # 结果:res1 = [1, 2, [1, 2, 3]]
res1[2][1] = 4 # 结果:res1 = [1, 2, [1, 4, 3]]
print(b) # 结果:b = [1, 2, [1, 4, 3]]
一般写法: 常规复制方式
- 只是将另一个名称关联到列表
- 对这个复制列表的修改都会直接改变原始列表
a = [1, 2, 3]
b = a # 结果:b = [1, 2, 3]
b[1] = 4 # 结果:b = [1, 4, 3]
print(a) # 结果:a = [1, 4, 3]
2) 列表深拷贝
在某些场景下,需要复制当前列表去做一些处理
推荐写法: 使用Python3的标准库,copy模块的deepcopy()函数
- 需要导入copy模块
- 在浅拷贝的情况下,当复制的对象包含子对象时,复制列表和原始列表没有完全独立
- 深拷贝能够实现子对象的拷贝
- 对复制列表子对象的更新不会改变原始列表
import copy
a = [1, 2, 3]
# 当copy的对象不包含子对象时
res = copy.deepcopy(a) # 结果:res = [1, 2, 3]
res[1] = 4 # 结果:res = [1, 4, 3]
print(a) # 结果:a = [1, 2, 3]
b = [1, 2, [1, 2, 3]]
# 当copy的对象包含子对象时
res1 = copy.deepcopy(b) # 结果:res1 = [1, 2, [1, 2, 3]]
res1[2][1] = 4 # 结果:res1 = [1, 2, [1, 4, 3]]
print(b) # 结果:b = [1, 2, [1, 2, 3]]
3. 基础操作
1) 获取列表的长度
在很多场景下,都需要获取列表的长度
推荐写法: 使用Python3的标准库,内置函数len()
lst = [1, 2, 3, 'a', 'b']
res = len(lst) # 结果:res = 5
# 对空列表取长度
lst = []
res = len(lst) # 结果:res = 0
2) 列表保序去重
在某些场景下,需要去除列表中的重复元素,并且列表中的元素保持原来的顺序
一般写法: 使用Python3的标准库,内置函数fromkeys()
- 将列表转换为字典
- 字典的键不能重复,实现去重
lst = [1, 4, 3, 3, 2, 2, 4]
# 转换为字典并取出键
lst_dict = {}.fromkeys(lst).keys() # 结果:dict_keys([1, 4, 3, 2])
# 重新转换为list
format_list = list(lst_dict) # 结果:format_list = [1, 4, 3, 2]
一般写法: 使用循环遍历的方式取出不重复的元素
- 这种方式可行,但是不够简洁
lst = [1, 4, 3, 3, 2, 2, 4]
format_list = []
for i in lst:
if i not in format_list:
format_list.append(i)
print(format_list) # 结果:format_list = [1, 4, 3, 2]
一般写法: 使用Python3的标准库,引入functools模块的reduce()函数
- 需要导入functools模块的reduce()函数
from functools import reduce
lst = [1, 4, 3, 3, 2, 2, 4]
# 将lst转换为[[], 1, 4, 3...],再使用reduce()函数的特性进行运算去重
reduce(lambda x, y: x if y in x else x + [y], [[], ] + lst) # 结果:[1, 4, 3, 2]
3) 列表不保序去重
在某些场景下,需要去除列表中的重复元素
一般写法: 使用Python3的标准库,内置函数set()和list()
- 将列表转换为set,去重后重新转换为列表
- set是无序不重复元素的序列
- 去重的结果没有保持原来的顺序,如果需要原来的顺序,可以重新排序
lst = [1, 4, 3, 3, 2, 2, 4]
# 转换为set
lst_set = set(lst) # 结果:lst_set = {1, 2, 3, 4}
# 重新转换为list
format_list = list(lst_set) # 结果:format_list = [1, 2, 3, 4]
# 可以按照index再次排序
format_list.sort(key=lst.index)
print(format_list) # 结果:format_list = [1, 4, 3, 2]
一般写法: 使用Python3的标准库,itertools模块的groupby()函数
- 去重之前需要先进行排序,因此去重后的结果不能保持原来的顺序
import itertools
lst = [1, 4, 3, 3, 2, 2, 4]
# 先排序
lst.sort()
it = itertools.groupby(lst)
res = []
for k, g in it:
res.append(k)
print(res) # 结果:res = [1, 2, 3, 4]
4) 二维列表扁平化为一维列表
将二维列表降维,获得一维列表。
推荐写法: 使用Python3的标准库,内置函数:sum(iterable[, start]),start为可选参数
- 用于以start为基础,从左到右与可迭代对象的所有元素相“加”,并返回结果
- iterable用于指定一个可迭代对象,这里是一个列表实例
- start用于指定一个起始值(默认为0),这里是一个空列表
list1 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
list2 = sum(list1, [])
print(list2) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
list3 = [["hello", "world"], ["hello", "python"], ["hello", "java"]]
list4 = sum(list3, [])
print(list4) # ['hello', 'world', 'hello', 'python', 'hello', 'java']
推荐写法: 使用列表推导式
- 在列表推导式中使用两个“for”语句,一个用于遍历二维列表下标,一个用于遍历子列表
list1 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
list2 = [x for i in range(len(list1)) for x in list1[i]]
print(list2) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
list3 = [["hello", "world"], ["hello", "python"], ["hello", "java"]]
list4 = [x for i in range(len(list3)) for x in list3[i]]
print(list4) # ['hello', 'world', 'hello', 'python', 'hello', 'java']
4. 列表添加
1) 添加单个元素到列表尾
在列表的尾部插入元素
推荐写法: 使用Python3的标准库,append()函数
lst = [1, 2, 3]
lst.append(4) # 结果:lst = [1,2,3,4]
一般写法: '+'运算符拼接
lst = [1, 2, 3]
lst1 = [4]
res = lst + lst1 # 结果:res = [1, 2, 3, 4]
2) 添加单个元素到列表指定位置
在列表的指定位置插入元素
- 推荐写法: 使用Python3的标准库,insert()函数
lst.insert(index, value)
lst1 = [1, 2, 3]
lst1.insert(3, 4) # 结果:lst1 = [1, 2, 3, 4]
lst2 = ['James', 'Harden', 'Curry']
lst2.insert(2, 'Leonard') # lst2 = ['James', 'Harden', 'Leonard', 'Curry']
# 当abs(index)大于列表的长度时,会将元素直接插入到列表尾部(index>0)或者开头(index<0)
lst3 = [1, 2, 3]
lst3.insert(6, 4) # lst3 = [1, 2, 3, 4]
推荐写法: 使用Python3的标准库,bisect模块的insort函数
- 向有序列表添加元素,元素会按照默认排序添加到对应位置
import bisect
lst = [1, 2, 3, 40]
bisect.insort(lst, 4) # 结果:lst = [1, 2, 3, 4, 40]
lst1 = ['a', 'c', 'd']
bisect.insort(lst1, 'b') # 结果:lst1 = ['a', 'b', 'c', 'd']
3) 添加列表到另一个列表
将多个列表拼接为一个新的列表
推荐写法: 使用Python3的标准库,内置函数extend()
- extend()函数不同于常规的拼接,它将修改被扩展的列表
a = [1, 2, 3]
b = [4, 5, 6]
a.extend(b) # 结果:a = [1, 2, 3, 4, 5, 6]
c = [1, 2, 3]
# 重复添加指定元素
c.extend([4] * 5) # 结果:c = [1, 2, 3, 4, 4, 4, 4, 4]
# 添加指定范围的元素
d = [1, 2, 3]
d.extend(range(5)) # 结果:d = [1, 2, 3, 0, 1, 2, 3, 4]
一般写法: 使用解包方式拼接
- 不会修改原有列表,返回一个新的列表
a = [1, 2, 3]
b = [4, 5, 6]
c = [*a, *b] # 结果:c = [1, 2, 3, 4, 5, 6]
c = [*a, *range(4, 7)] # 结果:c = [1, 2, 3, 4, 5, 6]
一般写法: 使用’+'运算符直接拼接
- 使用’+'号拼接时,会返回一个全新的列表,而不会改变原来的列表
a = [1, 2, 3]
b = [4, 5, 6]
print(a + b) # 结果:a+b = [1, 2, 3, 4, 5, 6],注意,此时a = [1, 2, 3]
# 如果想要改变列表a的值,达到和extend函数相同的效果,则需要重新赋值给a
# 这种拼接方式,效率比extend低
a = a + b # 结果:a = [1, 2, 3, 4, 5, 6]
一般写法: 使用切片赋值的方式拼接
- 这种方式可行,但可读性不是很高
a = [1, 2, 3]
b = [4, 5, 6]
# 切片时start位置大于等于len(a)即可,如果小于len(a)则相当于替换a中的元素
a[len(a):] = b # 结果:a = [1, 2, 3, 4, 5, 6]
c = [1, 2, 3]
d = [4, 5, 6]
# 将列表的部分与另一列表拼接
c[:1] = d # 结果:c = [4, 5, 6, 2, 3]
5. 列表删除
1) 移除列表中的单个元素
移除列表中的单个元素并返回
推荐写法: 使用Python3的标准库,内置函数pop()
- pop是唯一既修改列表又返回一个非None值的列表方法
- pop()可以指定移除元素的index,默认从列表尾部开始移除
- 当指定index时,需要注意每次pop,列表的index都会更新
lst = [4, 6, 5, 'a', 'b']
# 从列表尾部移除
lst.pop() # 返回移除的元素:'b'
# 指定index移除列表中的元素
lst.pop(2) # 返回移除的元素:5
# 此时列表中只有三个元素,index已经更新
lst.pop(3) # 结果:IndexError:pop index out of range,为了避免这种错误,可以在pop前使用len()函数确认列表长度
2) 删除列表中的单个元素
从列表中删除一个元素
推荐写法: 使用Python3的标准库,内置函数del()
- 根据下标删除元素
- 需要注意的是,每次删除都会改变列表内元素的下标
lst = ['a', 'e', 'f', 'a', 'b']
# 当index不存在时,会引发IndexError
# 为了避免IndexError,可以在删除元素前使用len()函数确认列表长度
del lst[1] # 指定index删除元素,结果:lst = ['a', 'f', 'a', 'b']
推荐写法: 使用Python3的标准库,内置函数remove()
- 根据值删除元素
- 当删除的元素值在列表中存在多个时,从列表头部开始顺序删除
- 每次删除都会改变列表内元素的下标
lst = [1, 2, 3, 'a', 'b', 'a']
lst.remove('a') # 指定删除的元素值,结果:lst = [1, 2, 3, 'b', 'a']
lst.remove('a') # 结果:lst = [1, 2, 3, 'b']
# 当删除的元素在列表中不存在时,引发错误:ValueError
# 为了避免引发ValueError,在删除之前可以使用in运算符判断元素是否存在,并使用count()函数判断该元素的个数
lst.remove('a') # 结果:ValueError: list.remove(x): x not in list
3) 删除列表中特定值的所有元素
当列表中存在重复元素时,根据值删除的方法只会删除匹配的第一个元素,某些场景下,可能需要同时删除列表中匹配的所有元素
推荐写法: 使用while循环的方式删除列表中指定值的全部元素
lst = ['a', 'c', 'd', 'a', 'a', 'b']
while 'a' in lst:
lst.remove('a')
print(lst) # lst = ['c', 'd', 'b']
一般写法: 使用for循环的方式删除列表中指定值的全部元素
- 需要注意的是,使用for循环遍历的时候要从后往前遍历,否则会出现IndexError,这是因为删除元素之后,列表的最大下标也变了
lst = ['a', 'c', 'd', 'a', 'a', 'b']
for i in range(len(lst) - 1, -1, -1):
if lst[i] == 'a':
lst.remove('a')
print(lst) # 结果:lst = ['c', 'd', 'b']
一般写法: 使用推导式方式
- 本质是从原列表中取出所有非指定元素,返回一个新列表
lst = ['a', 'c', 'd', 'a', 'a', 'b']
res = [lst[i] for i in range(len(lst)) if lst[i] != 'a'] # 结果:res = ['c', 'd', 'b']
一般写法: 使用Python3的标准库,filter和lambda表达式
- 通过filter过滤掉指定元素
- filter的返回值是filter对象,因此需要使用list函数重新转换为列表
lst = ['a', 'c', 'd', 'a', 'a', 'b']
res = list(filter(lambda x: x != 'a', lst)) # 结果:res = ['c', 'd', 'b']
4) 批量删除列表中的元素
删除列表中的部分元素
推荐写法: 使用Python3的标准库,内置函数del()
lst = [1, 2, 3, 'a', 'b']
# 删除下标从1到4(不含4)的元素
del lst[1:4] # 结果:lst = [1, 'b']
# 清除列表中的所有元素
del lst[:] # 结果:lst = []
推荐写法: 使用Python3的标准库,内部函数clear()
- 清除列表中的所有元素,保留空列表
lst = [1, 2, 3, 'a', 'b']
lst.clear() # 结果:lst = []
5) 删除整个列表
删除整个列表
推荐写法: 使用Python3的标准库,内置函数del()
- 删除引用,再使用这个名称的引用会引发错误:NameError: name ‘lst’ is not defined
lst = [1, 2, 3, 'a', 'b']
del lst
6. 列表替换
1) 替换列表中的某个元素
替换列表中的某个元素
推荐写法: 使用[]根据下标直接替换
lst = [1, 2, 'a', 'b']
lst[1] = 'c'
print(lst) # 结果:[1, 'c', 'a', 'b']
2) 批量替换列表中的元素
批量替换列表中的元素
推荐写法: 使用切片赋值的方式替换
lst = [1, 2, 3, 'a', 'b']
lst[3:] = [4, 5] # 结果:lst = [1, 2, 3, 4, 5]
# 替换的元素数量不必相等
lst1 = [1, 2, 3]
lst1[1:] = [4, 5, 6, 7] # 结果:lst1 = [1, 4, 5, 6, 7]