python之List操作(下)
7. 列表查找
1) 根据index获取元素值
根据index获取元素的值
推荐写法: 根据index获取元素值
lst = [1, 2, 'a', 'b']
res = lst[1] # 获取下标为1的元素,结果:res = 2
res = lst[-2] # 逆序获取下标为-2的元素值,结果:res = 'a'
# 当index>=len(lst)或者index<-len(lst)时,引发错误IndexError
res = lst[4] # 结果:IndexError: list index out of range
res = lst[-5] # 结果:IndexError: list index out of range
2) 获取列表的首尾元素
获取列表的首尾元素
推荐写法: 根据index获取列表的首尾元素
a = [1, 2, 3, 4]
# 获取列表的第一个元素
start = a[0] # 结果:start = 1
# 获取列表的最后一个元素
end = a[-1] # 结果:end = 4
3) 查找某元素出现的次数
查找列表中某个元素出现的次数
推荐写法: 使用Python3的标准库,内置函数count()
lst = [1, 2, 3, 4, 2, 1]
lst.count(1) # 结果:2
# 当元素在列表中不存在时,返回0
lst.count(5) # 结果:0
一般写法: 使用Python3的标准库,collections模块的Counter()函数
- 需要引入collections模块
- 返回的是列表中所有元素的出现次数
from collections import Counter
lst = [2, 1, 3, 4, 2, 1, 3, 1]
c = Counter(lst) # 结果:c = Counter({1: 3, 2: 2, 3: 2, 4: 1})
count2 = c[2] # 结果:count2 = 2 返回对应值的出现次数
4) 查找列表中的最大值/最小值
某些场景下,需要获取列表中最大或者最小的元素
推荐写法: 使用Python3的标准库,内置函数max()和min()
lst = [1, 2, 3, 4]
# 获取最大值
max(lst) # 结果:4
# 获取最小值
min(lst) # 结果:1
5) 查找列表是否包含某个元素
某些场景下,需要判断列表是否包含某个特定的元素
推荐写法: 使用in运算符
lst = [1, 2, 3, 'a']
# 结果:True
if 'a' in lst:
"""do something"""
推荐写法: 使用Python3的标准库,list类内置函数:index(x)
lst = [1, 2, 3, 'a']
# 列表中存在该元素时 ,会返回此元素首次出现的下标
lst.index('a') # 结果:3
# 列表中不存在该元素时,会产生ValueError
lst.index('b') # 结果:ValueError:'b' is not in list
推荐写法: 使用Python3的标准库,list类内置函数:count(x)
lst = [1, 2, 3, 'a']
# 列表中存在该元素时 ,会返回此元素出现的次数
lst.count('a') # 结果:1
# 列表中不存在该元素时,会返回0
lst.count('b') # 结果:0
6) 查找列表中某个元素的index
根据value获取在元素的索引值
推荐写法: 使用Python3的标准库,list类内置函数:index(x)
- 当查找的元素在列表中有重复值时,index()函数只能获取到第一个匹配元素的index
a = [1, 2, 3, 3, 'a', 'b']
a.index('a') # 结果:4
a.index(3) # 结果:2
# 当该元素在列表中不存在时,引发错误:ValueError
a.index('c') # 结果:ValueError: 'c' is not in list
7) 查找列表中某个重复元素的index集合
当列表中存在重复元素时,可能需要获取所有重复元素的索引
一般写法: 使用遍历的方式
def duplicates(lst1, item):
return [i for i, x in enumerate(lst1) if x == item]
lst = [1, 2, 3, 4, 2, 2, 2]
res = duplicates(lst, 2) # 结果:res = [1, 4, 5, 6]
一般写法: 使用切片的方式
lst = [1, 2, 3, 4, 2, 2, 2]
# 获取第一个index
first = lst.index(2) # first = 1
# 从列表中下标为2的元素开始查找
second = lst[2:].index(2) + first + 1 # second = 4
# 依次往下查找,直至遍历整个列表,最终结果为
res = [1, 4, 5, 6]
一般写法: 使用Python3的标准库,collections模块的defaultdict()函数
- 获取列表中所有元素的index集合
from collections import defaultdict
lst = [1, 2, 3, 4, 2, 2, 2]
d = defaultdict(list)
for k, va in [(v, i) for i, v in enumerate(lst)]:
d[k].append(va)
print(d) # 结果:defaultdict(<class 'list'>, {1: [0], 2: [1, 4, 5, 6], 3: [2], 4: [3]})
8) 线性查找列表中某个元素的index
使用线性查找算法,判断列表是否包含某个特定的元素,若元素存在,则返回该元素的下标
def linear_search(lst, x):
for i in range(len(lst)):
if lst[i] == x:
return i
return -1
# 函数调用
list1 = [3, 4, 5, 5, 6, 6, 7, 8, 9]
print(linear_search(list1, 5)) # 2
print(linear_search(list1, 100)) # -1
9) 二分法查找有序列表中某个元素的index
对于有序列表,使用二分查找算法,判断列表是否包含某个特定的元素,若元素存在,则返回该元素的下标
def binary_search(lst, left, right, x):
if left <= right:
mid = int((left + right) / 2)
if lst[mid] == x:
return mid
elif lst[mid] > x:
return binary_search(lst, left, mid - 1, x)
elif lst[mid] < x:
return binary_search(lst, mid + 1, right, x)
else:
return -1
else:
return -1
# 函数调用
list1 = [3, 4, 5, 6, 7, 8, 9]
print(binary_search(list1, 0, len(list1) - 1, 5)) # 2
print(binary_search(list1, 0, len(list1) - 1, 8)) # 5
print(binary_search(list1, 0, len(list1) - 1, 2)) # -1
print(binary_search(list1, 0, len(list1) - 1, 100)) # -1
8. 列表转换
1) 列表转字符串
将列表内的元素转换为一个字符串
推荐写法: 使用Python3的标准库,内置函数str()
- join()函数只能对字符串对象进行拼接,其他对象的拼接会引发TypeError
lst = ['hello', 'world']
res = " ".join(lst) # 结果:res = 'hello world'
lst1 = ['hello', 'world', 12]
res = " ".join(lst1) # 结果:TypeError: sequence item 2: expected str instance, int found
# 需要将int类型的元素转换为字符串时,可以先将该元素转换为字符串类型
lst2 = [str(i) for i in lst1]
res = " ".join(lst2) # 结果:res = 'hello world 12'
2) 字符串转列表
将一个字符串转换为列表
推荐写法: 使用Python3的标准库,内置函数split()
- split()函数可以以字符串中包含的任意字符作为分隔符,将字符串转换为列表
- 分隔符不存在时,不作分割直接转换为单个元素的列表
str1 = "hello python world"
# 以空格作为分隔符
res = str1.split(" ") # 结果:res = ['hello', 'python', 'world']
# 当分隔符在字符串中不存在时,将整个字符串转换为列表元素
res1 = str1.split("a") # 结果:res1 = ['hello python world']
一般写法: 使用Python3的标准库,内置函数list()
- 将字符串中的每个字符转换为列表的元素
str1 = "hello world"
res = list(str1) # 结果:res = ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
3) 列表转元组
将列表转换为元组
推荐写法: 使用Python3的标准库,内置函数tuple()
- 当需要将多个列表转换为一一对应的元组时,可以使用zip()函数
- 当两个列表的长度不一致时,多出的元素在另一个列表无匹配的元素时就不展示多出的元素
- zip()函数返回的是一个zip对象,可以根据需要转换为其他对象
lst = [1, 2, 'a', 'b']
tup = tuple(lst) # 结果:tup = (1, 2, 'a', 'b')
# 列表长度一致时
lst1 = [1, 2, 3]
lst2 = ['a', 'b', 'c']
tup = tuple(zip(lst1, lst2)) # 结果:tup = ((1, 'a'), (2, 'b'), (3, 'c'))
# 列表长度不一致时
lst3 = ['a', 'b', 'c', 'd']
tup = tuple(zip(lst1, lst3)) # 结果:tup = ((1, 'a'), (2, 'b'), (3, 'c'))
4) 元组转列表
将元组转换为列表
推荐写法: 使用Python3的标准库,内置函数list()
- 当需要将多个元组转换为一一对应的列表时,可以使用zip()函数
- 当两个列表的长度不一致时,多出的元素在另一个列表无匹配的元素时就不展示多出的元素
- zip()函数返回的是一个zip对象,可以根据需要转换为其他对象
tup = (1, 2, 'a', 'b')
lst = list(tup) # 结果:lst = [1, 2, 'a', 'b']
# 元组长度一致时
tup1 = (1, 2, 3)
tup2 = ('a', 'b', 'c')
lst = list(zip(tup1, tup2)) # 结果:lst = [(1, 'a'), (2, 'b'), (3, 'c')]
# 元组长度不一致时
tup3 = ('a', 'b', 'c', 'd')
lst = list(zip(tup1, tup3)) # 结果:lst = [(1, 'a'), (2, 'b'), (3, 'c')]
5) 列表转字典
将列表转换成字典
推荐写法: 使用Python3的标准库,内置函数zip()、dict()
- 列表不能直接用dict()函数转换为字典
- 当两个列表的长度不一致时,多出的元素在另一个列表无匹配的元素时就不展示多出的元素
- 作为key值的列表中如果存在重复元素,会被去重,因为字典不允许重复的key
keys = [1, 2, 3, 4]
values = ['a', 'b', 'c', 'd']
res = dict(zip(keys, values)) # 结果:res = {1: 'a', 2: 'b', 3: 'c', 4: 'd'}
# 当两个列表的长度不一致时
keys = [1, 2, 3]
values = ['a', 'b', 'c', 'd']
res1 = dict(zip(keys, values)) # 结果:res1 = {1: 'a', 2: 'b', 3: 'c'}
推荐写法: 使用Python3的标准库,内置函数dict.fromkeys()
- 需要注意的是,当列表中存在重复元素时,会被去重,因为字典的key值不允许重复
# 创建value为空的字典
keys = [1, 2, 3, 4]
values = []
dicts = dict.fromkeys(keys, values) # dicts = {1: [], 2: [], 3: [], 4: []}
# key值存在重复时
keys = [1, 2, 3, 3]
values = []
dicts = dict.fromkeys(keys, values) # dicts = {1: [], 2: [], 3: []}
# 当value不为空时,转换的字典不是两个列表元素一一对应
keys = [1, 3, 4]
values = ['a', 'b', 'c']
dicts = dict.fromkeys(keys, values) # dicts = {1: ['a', 'b', 'c'], 3: ['a', 'b', 'c'], 4: ['a', 'b', 'c']}
一般写法: 使用嵌套列表转换为字典
- 转换的列表只能含有两个元素,分别代表字典的键和值
- 作为key值的列表中如果存在重复元素,会被去重,因为字典不允许重复的key
a = [1, 2]
b = ['a', 'b']
c = [a, b]
res = dict(c) # 结果:res = {1: 2, 'a': 'b'}
a1 = [1, 'a']
b1 = [2, 'b']
c1 = [3, 'c']
d = [a1, b1, c1]
res1 = dict(d) # 结果:res1 = {1: 'a', 2: 'b', 3: 'c'}
# 当列表内元素不是两个时,引发ValueError
a2 = [1, 2, 3]
b2 = ['a', 'b', 'c']
c2 = [a2, b2]
res2 = dict(c2) # 结果:ValueError: dictionary update sequence element #0 has length 3; 2 is required
6) 字典转列表
字典转换成列表
推荐写法: 使用Python3的标准库,内置函数list()
# 将字典的键转换成列表
dict1 = {'name': 'Mark', 'age': 25, 'gender': 'male', 'phone': 1234}
res = list(dict1) # 结果:res = ['name', 'age', 'gender', 'phone']
res1 = list(dict1.keys()) # 结果:res1 = ['name', 'age', 'gender', 'phone']
# 将字典的值转换成列表
dict2 = {'name': 'Mark', 'age': 25, 'gender': 'male', 'phone': 1234}
res2 = list(dict2.values()) # 结果:res2 = ['Mark', 25, 'male', 1234]
9. 列表比较
1) 考虑元素顺序的列表比较
按照列表的默认顺序对元素进行比较
推荐写法: 使用Python3的标准库,operator模块
- 从第一个元素顺序开始比较,如果相等,则继续,返回第一个不相等元素比较的结果。如果所有元素比较均相等,则长的列表大,一样长则两列表相等
- 元素比较只能在同类型元素之间进行,否则会引发错误TypeError
import operator
lst1 = [1, 2, 3, 4, 'a']
lst2 = [1, 2, 3, 4, 'a']
operator.eq(lst1, lst2) # 结果:True,相当于运算符‘==’
lst1 = [1, 2, 3, 4, 'a']
lst2 = [1, 3, 4, 2, 'a']
operator.eq(lst1, lst2) # 结果:False
推荐写法: 使用运算符比较
- 从第一个元素顺序开始比较,如果相等,则继续,返回第一个不相等元素比较的结果。如果所有元素比较均相等,则长的列表大,一样长则两列表相等
- 元素比较只能在同类型元素之间进行,否则会引发错误TypeError
lst1 = [1, 2, 3, 4, 'a']
lst2 = [1, 2, 3, 4, 'a']
lst1 == lst2 # 结果:True
lst1 = [1, 2, 3, 4, 'a']
lst2 = [1, 3, 4, 2, 'a']
lst1 == lst2 # 结果:False
2) 忽略元素顺序的列表比较
比较两个列表内的元素是否相等,不考虑排列顺序
推荐写法: 使用Python3的标准库,collections模块的Counter()函数
- 需要导入collections模块
- Counter()函数的本质是取出列表中的所有元素及其出现的次数进行比较
- 列表中的元素必须可哈希
- Counter()函数的比较不需要对列表进行排序,因此可以实现包含不同类型对象的列表之间的比较
from collections import Counter
lst1 = [1, 2, 3, 4, 'a']
lst2 = [4, 2, 1, 'a', 3]
Counter(lst1) == Counter(lst2) # 结果:True
lst1 = [1, 2, 3, 'a']
lst2 = [1, 3, 4, 'n']
Counter(lst1) == Counter(lst2) # 结果:False
3) 忽略元素顺序的混合列表比较
很多情况下,列表中包含的元素类型可能比较复杂,难以排序,此时需要自定义的比较器来比较列表中的元素是否相
等
一般写法: 使用Python3的标准库,内置函数remove()、len()
- 首先比较两个列表的长度,如果长度不一致,则返回False,如果长度一致则比较元素值
- 循环比较列表1中的元素在列表2中是否存在,如果存在则从列表2中将对应元素删除,继续比较下一个元素,直到所有元素比较完成返回结果:True;如果有元素不存在则返回比较结果:False
- 使用remove()函数,是为了避免存在重复元素,影响比较结果
- 因为使用remove()函数,会改变原来的列表,应使用拷贝的副本进行比较
def equal(x, y):
if len(x) == len(y):
for i in x:
if i in y:
y.remove(i)
else:
return False
else:
return False
return True
lst1 = [1, 3, [1, 2], 'a']
lst2 = [2, 3, [1, 2], 1]
equal(lst1, lst2.copy()) # 结果:False
lst1 = [1, 3, [1, 2]]
lst2 = [2, 3, [1, 2], 1]
equal(lst1, lst2.copy()) # 结果:False
lst1 = [1, 2, 3, [1, 2]]
lst2 = [2, 3, [1, 2], 1]
equal(lst1, lst2.copy()) # 结果:True
10. 列表截取
1) 列表截取
截取列表的一部分
推荐写法: 使用切片[]方式截取
lst = [1, 2, 4, 3, 'hello', 'world']
# 截取指定位置开始的列表
res = lst[1:] # 结果:res = [2, 4, 3, 'hello', 'world']
# 截取开头到指定位置的列表
res1 = lst[:3] # 结果: res1 = [1, 2, 4]
# 截取指定范围内的列表
res2 = lst[1:4] # 结果:res2 = [2, 4, 3]
# 指定步长截取,当步长为负数时,从右向左截取
res3 = lst[1:5:2] # 结果:res3 = [2, 3]
res4 = lst[-2:-5:-2] # 结果:res4 = ['hello', 4]
# 截取整个列表,步长为-1时,逆序截取整个列表
res5 = lst[::] # 结果:res5 = [1, 2, 4, 3, 'hello', 'world']
res6 = lst[::-1] # 结果:res6 = ['world', 'hello', 3, 4, 2, 1]
11.列表遍历
1) 直接遍历列表
遍历一个列表,处理其中的元素
推荐写法: 使用Python3的标准库,内置函数enumerate()
lst = [1, 2, 3, 'a', 'b']
# 遍历列表获取value
res = []
for element in lst:
res.append(element) # 结果:res = [1, 2, 3, 'a', 'b']
# 遍历列表的同时获取index和value
for index, value in enumerate(lst):
print('index:{},value:{}'.format(index, value))
# 结果:
# index:0,value:1
# index:1,value:2
# index:2,value:3
# index:3,value:a
# index:4,value:b
2) 根据index遍历列表
根据index遍历
推荐写法: 使用Python3的标准库,内置函数len()和range()
lst = [1, 2, 3, 'a', 'b']
res = []
for i in range(len(lst)):
res.append(lst[i])
# 结果:res = [1, 2, 3, 'a', 'b']
12. 列表排序
1) 列表默认排序
按照默认方式对列表中的元素排序
推荐写法: 使用Python3的标准库,内置函数sort()
- sort()函数的排序是永久性的,会修改原来的列表,无法恢复
- 不能对一个包含不同类型元素的列表排序,引发TypeError
- sort()函数不会返回排序后的列表,因此res = list.sort()这样的赋值是没有意义的,res = None
# 整数列表排序
lst = [1, 2, 4, 2, 3, 5]
lst.sort() # 结果:lst = [1, 2, 2, 3, 4, 5]
# 字符串列表排序
lst1 = ['world', '!', 'python', 'hello']
lst1.sort() # 结果:lst1 = ['!', 'hello', 'python', 'world']
# 列表中包含不同类型的元素
lst2 = [2, 1, 'world']
lst2.sort() # 结果:TypeError: '<' not supported between instances of 'int' and 'str'
推荐写法: 使用Python3的标准库,内置函数sorted()
- sorted()函数的排序是暂时性的,只会展示排序后的列表,不会修改原来的列表
- sorted()函数有可选参数reverse,默认为False,当置为True时,将排序后的列表逆序
- 不能对一个包含不同类型元素的列表排序,引发TypeError
# 整数列表排序
lst = [1, 2, 4, 2, 3, 5]
sorted(lst) # 结果:[1, 2, 2, 3, 4, 5]
sorted(lst, reverse=True) # 结果:[5, 4, 3, 2, 2, 1]
# 字符串列表排序
lst1 = ['world', '!', 'python', 'hello']
sorted(lst1) # 结果:['!', 'hello', 'python', 'world']
sorted(lst1, reverse=True) # 结果:['world', 'python', 'hello', '!']
# 列表中包含不同类型的元素
lst2 = [2, 1, 'world']
sorted(lst2) # 结果:TypeError: '<' not supported between instances of 'int' and 'str'
2) 列表逆序
将列表中的元素逆序排列
推荐写法: 使用Python3的标准库,内置函数reverse()
- reverse()函数的逆序是永久性的,会修改列表,但是随时可以通过再次调用reverse()函数恢复
- reverse()函数没有返回值,因此res = list.reverse()这样的赋值是没有意义的,res = None
# 整数列表
lst = [1, 2, 4, 2, 3, 5]
lst.reverse() # 结果:lst = [5, 3, 2, 4, 2, 1]
# 字符串列表
lst1 = ['world', '!', 'python', 'hello']
lst1.reverse() # 结果:lst1 = ['hello', 'python', '!', 'world']
# 列表中包含不同类型的元素
lst2 = [2, 1, 'world']
lst2.reverse() # 结果:lst2 = ['world', 1, 2]
推荐写法: 使用Python3的标准库,内置函数reversed()
- reversed()函数会将列表逆序的结果存储到迭代器,不会改变原来的列表,也不会创建副本,只会多出迭代器对象所占的空间,比较高效
# 整数列表
lst = [1, 2, 4, 2, 3, 5]
res = []
for item in reversed(lst):
res.append(item) # 结果:res = [5, 3, 2, 4, 2, 1]
# 字符串列表
lst1 = ['world', '!', 'python', 'hello']
res1 = []
for item in reversed(lst1):
res1.append(item) # 结果:res1 = ['hello', 'python', '!', 'world']
# 列表中包含不同类型的元素
lst2 = [2, 1, 'world']
res2 = []
for item in reversed(lst2):
res2.append(item) # 结果:res2 = ['world', 1, 2]
一般写法: 使用切片[::-1]逆序
# 整数列表
lst = [1, 2, 4, 2, 3, 5]
res = lst[::-1] # 结果:res = [5, 3, 2, 4, 2, 1]
# 字符串列表
lst1 = ['world', '!', 'python', 'hello']
res1 = lst1[::-1] # 结果:res1 = ['hello', 'python', '!', 'world']
# 列表中包含不同类型的元素
lst2 = [2, 1, 'world']
res2 = lst2[::-1] # 结果:res2 = ['world', 1, 2]