MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Python使用列表部分内容的技巧

2023-07-091.4k 阅读

切片操作

在Python中,列表切片是访问列表部分内容的重要方式,它的基本语法为 list[start:stop:step]。其中 start 是切片的起始索引(包括该索引位置的元素),stop 是切片的结束索引(不包括该索引位置的元素),step 是步长,默认为1。

简单切片获取子列表

例如,我们有一个包含数字1到10的列表:

nums = list(range(1, 11))
print(nums[2:5])  

在上述代码中,nums[2:5] 表示从索引2(即元素3)开始,到索引5(但不包括元素6)结束,所以输出为 [3, 4, 5]

如果省略 start,则从列表开头开始切片:

nums = list(range(1, 11))
print(nums[:5])  

这里 nums[:5] 等价于 nums[0:5],输出为 [1, 2, 3, 4, 5]

同样,如果省略 stop,则切片到列表末尾:

nums = list(range(1, 11))
print(nums[5:])  

nums[5:] 表示从索引5(元素6)开始,一直到列表末尾,输出为 [6, 7, 8, 9, 10]

步长的使用

步长参数 step 可以用来控制切片时元素的间隔。例如,要每隔一个元素取一个:

nums = list(range(1, 11))
print(nums[::2])  

nums[::2] 表示从列表开头到末尾,每隔一个元素取一个,输出为 [1, 3, 5, 7, 9]

如果 step 为负数,则表示反向切片。例如:

nums = list(range(1, 11))
print(nums[::-1])  

nums[::-1] 会将列表反向,输出为 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

列表拼接与重复

在处理列表部分内容时,有时需要将多个列表拼接起来,或者重复某个列表的部分内容。

列表拼接

使用 + 运算符可以将两个列表拼接成一个新的列表。例如:

list1 = [1, 2, 3]
list2 = [4, 5, 6]
result = list1 + list2
print(result)  

上述代码将 list1list2 拼接在一起,输出为 [1, 2, 3, 4, 5, 6]

还可以使用 extend() 方法将一个列表的内容添加到另一个列表中。与 + 运算符不同,extend() 方法会直接修改原列表,而不是返回一个新列表:

list1 = [1, 2, 3]
list2 = [4, 5, 6]
list1.extend(list2)
print(list1)  

这里 list1 被修改为 [1, 2, 3, 4, 5, 6]

列表重复

使用 * 运算符可以重复列表的内容。例如,要重复一个列表3次:

list1 = [1, 2]
result = list1 * 3
print(result)  

输出为 [1, 2, 1, 2, 1, 2]

列表推导式与部分内容筛选

列表推导式是Python中创建列表的一种简洁方式,同时也可以用于筛选列表中的部分内容。

基本列表推导式

其基本语法为 [expression for item in iterable if condition],其中 expression 是对每个 item 进行操作后生成的新元素,if condition 是可选的筛选条件。

例如,我们有一个包含1到10的列表,要生成一个新列表,其中每个元素是原列表元素的平方:

nums = list(range(1, 11))
squares = [num ** 2 for num in nums]
print(squares)  

这里 [num ** 2 for num in nums] 就是列表推导式,它对 nums 中的每个元素 num 进行平方操作,生成新列表 squares,输出为 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

带有条件筛选的列表推导式

如果我们只想获取偶数的平方:

nums = list(range(1, 11))
even_squares = [num ** 2 for num in nums if num % 2 == 0]
print(even_squares)  

[num ** 2 for num in nums if num % 2 == 0] 中,if num % 2 == 0 作为筛选条件,只有满足该条件(即 num 为偶数)的元素才会进行平方操作并添加到新列表 even_squares 中,输出为 [4, 16, 36, 64, 100]

索引与查找

在处理列表部分内容时,找到特定元素的索引位置是常见需求。

查找元素索引

使用 index() 方法可以查找列表中某个元素的索引。例如:

fruits = ['apple', 'banana', 'cherry']
index = fruits.index('banana')
print(index)  

这里 fruits.index('banana') 会返回 banana 在列表 fruits 中的索引,输出为1。

需要注意的是,如果元素不存在于列表中,index() 方法会引发 ValueError。为了避免这种情况,可以先使用 in 关键字检查元素是否存在:

fruits = ['apple', 'banana', 'cherry']
if 'grape' in fruits:
    index = fruits.index('grape')
else:
    print('Element not found')

查找多个相同元素的索引

当列表中有多个相同元素时,index() 方法只会返回第一个匹配元素的索引。如果要获取所有匹配元素的索引,可以使用以下方法:

nums = [10, 20, 20, 30]
indices = [i for i, num in enumerate(nums) if num == 20]
print(indices)  

这里使用了列表推导式和 enumerate() 函数。enumerate() 函数同时返回元素和其索引,通过列表推导式筛选出值为20的元素的索引,输出为 [1, 2]

列表的删除与修改部分内容

在实际编程中,经常需要删除或修改列表中的部分元素。

删除元素

可以使用 del 语句根据索引删除列表中的元素。例如:

nums = [1, 2, 3, 4, 5]
del nums[2]
print(nums)  

del nums[2] 删除了索引为2的元素(即3),输出为 [1, 2, 4, 5]

也可以使用 remove() 方法根据元素值删除元素:

fruits = ['apple', 'banana', 'cherry']
fruits.remove('banana')
print(fruits)  

fruits.remove('banana') 删除了值为 banana 的元素,输出为 ['apple', 'cherry']。同样,如果元素不存在,remove() 方法会引发 ValueError

修改元素

通过索引可以直接修改列表中的元素。例如:

nums = [1, 2, 3, 4, 5]
nums[2] = 30
print(nums)  

这里将索引为2的元素从3修改为30,输出为 [1, 2, 30, 4, 5]

如果要修改多个连续元素,可以结合切片操作。例如,将列表中索引2到4(不包括4)的元素替换为新的列表:

nums = [1, 2, 3, 4, 5]
nums[2:4] = [30, 40]
print(nums)  

输出为 [1, 2, 30, 40, 5]

列表的排序与部分排序

排序是处理列表时常用的操作,有时我们可能只需要对列表的部分内容进行排序。

列表全排序

使用 sort() 方法可以对列表进行原地排序(即直接修改原列表)。例如:

nums = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
nums.sort()
print(nums)  

输出为 [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]

sort() 方法默认是升序排序,如果要进行降序排序,可以传递 reverse=True 参数:

nums = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
nums.sort(reverse=True)
print(nums)  

输出为 [9, 6, 5, 5, 5, 4, 3, 3, 2, 1, 1]

部分排序

假设我们有一个二维列表,每个子列表包含一个名字和对应的分数,我们只想对分数进行部分排序。例如:

students = [['Alice', 85], ['Bob', 78], ['Charlie', 92], ['David', 88]]
students[1:3] = sorted(students[1:3], key=lambda x: x[1])
print(students)  

这里先对索引1到3(不包括3)的子列表进行排序,排序依据是每个子列表的第二个元素(分数),sorted() 函数返回一个新的已排序列表,然后将其赋值回原列表的相应位置,输出为 [['Alice', 85], ['Bob', 78], ['Charlie', 92], ['David', 88]]

嵌套列表与部分内容访问

嵌套列表是指列表中的元素又是列表。访问嵌套列表的部分内容需要多层索引。

简单嵌套列表访问

例如,我们有一个嵌套列表表示矩阵:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix[1][2])  

这里 matrix[1] 表示取第二行(索引从0开始),即 [4, 5, 6],然后 matrix[1][2] 表示取这一行的第三个元素,输出为6。

访问嵌套列表中的子列表部分内容

如果要访问矩阵第二行的前两个元素:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix[1][:2])  

输出为 [4, 5]

列表的迭代与部分内容处理

在遍历列表时,有时只需要处理列表的部分内容。

使用切片进行部分迭代

例如,我们只迭代列表的前半部分:

nums = list(range(1, 11))
for num in nums[:5]:
    print(num)  

这里通过切片 nums[:5] 只迭代了列表的前5个元素,输出为1到5。

使用条件进行部分迭代

假设我们有一个包含数字和字符串的混合列表,只对其中的数字元素进行操作:

mixed_list = [1, 'two', 3, 'four', 5]
for item in mixed_list:
    if isinstance(item, int):
        print(item ** 2)  

这里通过 isinstance() 函数判断元素是否为整数,只对数字元素进行平方操作并输出,输出为1, 9, 25。

列表与其他数据结构结合处理部分内容

在实际编程中,列表经常与其他数据结构如字典、集合等结合使用,以更灵活地处理部分内容。

列表与字典结合

例如,我们有一个字典,键是名字,值是对应的分数列表。我们要找出所有分数大于80的人的名字和分数:

scores = {
    'Alice': [85, 90],
    'Bob': [78, 82],
    'Charlie': [92, 88]
}
result = [(name, score) for name, score_list in scores.items() for score in score_list if score > 80]
print(result)  

这里使用了嵌套的列表推导式,外层遍历字典的键值对,内层遍历分数列表,筛选出分数大于80的情况,输出为 [('Alice', 85), ('Alice', 90), ('Charlie', 92), ('Charlie', 88)]

列表与集合结合

假设我们有一个列表包含重复元素,我们要获取其中不重复的元素,并按原顺序保留部分元素。可以结合集合和列表:

nums = [1, 2, 2, 3, 4, 4, 5]
seen = set()
result = [num for num in nums if num not in seen and not seen.add(num)]
print(result)  

这里使用集合 seen 来记录已经见过的元素,通过列表推导式筛选出不重复的元素,并按原顺序保留,输出为 [1, 2, 3, 4, 5]

性能优化与列表部分内容操作

在处理大型列表的部分内容时,性能优化非常重要。

切片性能

切片操作在Python中是相对高效的,因为它不会立即创建一个新的列表对象,而是返回一个切片对象,只有在实际访问切片内容时才会创建新的列表。例如,对于一个非常大的列表:

big_list = list(range(1000000))
sub_list = big_list[1000:2000]

这里获取 big_list 的切片 sub_list 是比较快速的,因为并没有立即复制所有元素。

避免不必要的循环

在处理列表部分内容时,尽量使用内置函数和列表推导式,而不是手动编写循环。例如,要计算列表中部分元素的和,使用 sum() 函数结合切片会比手动循环更高效:

nums = list(range(1000000))
sub_sum = sum(nums[1000:2000])

相比手动编写循环逐个累加元素,sum() 函数是经过优化的,执行速度更快。

总结与最佳实践

在使用Python列表部分内容时,以下是一些最佳实践:

  1. 充分利用切片操作来获取、修改和删除列表的部分内容,它简洁且高效。
  2. 列表推导式是筛选和转换列表部分内容的强大工具,尽量使用它来替代冗长的循环。
  3. 在查找元素索引时,先使用 in 关键字检查元素是否存在,避免 ValueError
  4. 对于大型列表,注意性能优化,如使用切片的延迟计算特性和内置的高效函数。
  5. 结合其他数据结构,如字典和集合,以更灵活地处理列表部分内容。

通过掌握这些技巧和最佳实践,能够在Python编程中更高效、灵活地处理列表的部分内容,提升代码的质量和性能。