python之List操作(上)

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]
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值