Logo
Published on

2.15.列表

Authors
  • avatar
    Name
    xiaobai
    Twitter

1.列表是什么?

列表 是一个有序、可变的集合,可以存储任意数量、任意类型的元素。

  • 有序:元素有固定的位置(索引),按添加的顺序排列。
  • 可变:创建后,可以修改列表的内容(增、删、改)。
  • 异构:一个列表中可以包含不同类型的数据(整数、字符串、甚至其他列表)。

2.创建列表

有两种主要方式创建列表:

2.1.1. 使用方括号 [](最常用)

# 空列表
empty_list = []
print(empty_list) # []

# 包含元素的列表
numbers = [1, 2, 3, 4, 5]
fruits = ["apple", "banana", "orange"]
mixed = [1, "hello", 3.14, True] # 包含不同类型

print(numbers) # [1, 2, 3, 4, 5]
print(fruits)  # ['apple', 'banana', 'orange']
print(mixed)   # [1, 'hello', 3.14, True]

2.2.2. 使用 list() 构造函数

创建列表除了用方括号 [],也可以用内置的 list() 函数。 list() 可以将其他可迭代对象(如字符串、元组、字典、集合等)转换为列表。

  • 如果传入一个字符串,每个字符会成为列表中的一个元素。
  • 如果传入一个元组,列表会包含元组中的元素。
  • 如果不传参数,会得到一个空列表
# 从字符串创建(字符串是可迭代对象)
list_from_string = list("abc")
print(list_from_string) # ['a', 'b', 'c']

# 从元组创建
list_from_tuple = list((1, 2, 3))
print(list_from_tuple) # [1, 2, 3]

# 创建空列表
another_empty_list = list()
print(another_empty_list) # []

3.访问列表元素(索引和切片)

3.1.索引访问

列表使用从 0 开始的索引。

fruits = ["apple", "banana", "orange", "grape"]

print(fruits[0])   # "apple" - 第一个元素
print(fruits[1])   # "banana" - 第二个元素
print(fruits[-1])  # "grape" - 最后一个元素
print(fruits[-2])  # "orange" - 倒数第二个元素

注意:如果索引超出范围,会引发 IndexError

# print(fruits[10]) # 这会报错:IndexError

3.2.切片访问

切片用于获取列表的一个子集,语法:list[start:stop:step]

  • start:起始索引(包含)
  • stop:结束索引(不包含)
  • step:步长(默认为1)
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(numbers[2:5])    # [2, 3, 4]     # 索引2到5(不含5)
print(numbers[:4])     # [0, 1, 2, 3]  # 从开始到索引4
print(numbers[5:])     # [5, 6, 7, 8, 9] # 从索引5到结束
print(numbers[::2])    # [0, 2, 4, 6, 8] # 每隔一个取一个元素
print(numbers[::-1])   # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] # 反转列表

# 切片创建的是新列表,不影响原列表
sub_list = numbers[1:4]
print(sub_list) # [1, 2, 3]

4.修改列表(增、删、改)

由于列表是可变的,我们可以修改它。

4.1.修改元素

fruits = ["apple", "banana", "cherry"]
fruits[1] = "blueberry"  # 修改第二个元素
print(fruits) # ['apple', 'blueberry', 'cherry']

4.2.添加元素

在列表中添加元素,有多种常用方法:

  1. append(x) 在列表末尾添加一个元素 x
  2. insert(index, x) 在指定位置 index 插入元素 x,原有及后续元素后移。
  3. extend(iterable) 将另一个可迭代对象(如列表、元组等)的元素逐个添加到列表末尾。

注意

  • append() 是把一个元素作为整体添加到末尾。
  • extend() 会把所有元素分别添加到原列表。

例如:

a = [1, 2]
a.append([3, 4])
print(a)  # [1, 2, [3, 4]]  # 整个 [3, 4] 作为一个元素

b = [1, 2]
b.extend([3, 4])
print(b)  # [1, 2, 3, 4]    # 3 和 4 分别添加进列表
fruits = ["apple", "banana"]

# 方法1: append() - 在末尾添加单个元素
fruits.append("orange")
print(fruits) # ['apple', 'banana', 'orange']

# 方法2: insert() - 在指定位置插入元素
fruits.insert(1, "grape") # 在索引1处插入
print(fruits) # ['apple', 'grape', 'banana', 'orange']

# 方法3: extend() - 将另一个可迭代对象的元素逐个添加进来
fruits.extend(["mango", "pineapple"])
print(fruits) # ['apple', 'grape', 'banana', 'orange', 'mango', 'pineapple']

# 注意:append() 和 extend() 的区别
a = [1, 2]
a.append([3, 4])   # 将整个列表作为一个元素添加
print(a) # [1, 2, [3, 4]]

b = [1, 2]
b.extend([3, 4])   # 将列表中的元素逐个添加
print(b) # [1, 2, 3, 4]

4.3.删除元素

在操作列表时,常常需要删除其中的元素。Python 提供了多种删除列表元素的方法,主要包括:

  1. remove(x) 方法
    • 用于删除列表中第一个值为 x 的元素(如果没有这样的元素会抛出 ValueError)。
    • 只会删除找到的第一个匹配项。
    • 语法:list.remove(x)
  2. pop([index]) 方法
    • 用于删除并返回给定索引处的元素。如果没有指定索引,默认删除并返回最后一个元素。
    • 如果索引越界会抛出 IndexError。
    • 语法:list.pop()list.pop(index)
  3. del 语句
    • del 可以根据索引删除列表的指定元素,也可以一次性删除多个元素(切片)。
    • 语法:del list[index]del list[start:end]
  4. clear() 方法
    • 清空整个列表,变成空列表 []。
    • 语法:list.clear()

提示

  • remove()pop()/del 必须有元素才能删除,否则会报错。
  • 使用 del 删除变量本身(如 del mylist)会导致变量名不可用。
fruits = ["apple", "banana", "cherry", "banana", "date"]

# 方法1: remove() - 删除第一个匹配的元素
fruits.remove("banana")
print(fruits) # ['apple', 'cherry', 'banana', 'date']

# 方法2: pop() - 删除并返回指定索引的元素(默认最后一个)
popped_item = fruits.pop() # 删除最后一个
print(popped_item) # 'date'
print(fruits)      # ['apple', 'cherry', 'banana']

popped_item2 = fruits.pop(0) # 删除第一个
print(popped_item2) # 'apple'
print(fruits)       # ['cherry', 'banana']

# 方法3: del 语句 - 按索引删除
del fruits[0] # 删除第一个元素
print(fruits) # ['banana']

# 方法4: clear() - 清空整个列表
fruits.clear()
print(fruits) # []

常用用法与场景选择:

  • 删除某个具体元素(但不清楚索引)建议用 remove(x)
  • 需要获取并移除某个位置的值,可以用 pop(index)
  • 批量删除(切片)或彻底清空可用 delclear()
  • 若只是想新建空列表而不是清空原列表,可直接重新赋值:mylist = []

5.列表操作与方法

5.1.常用操作

列表除了可以“增删改查”,还可以做各种操作和应用。常见的列表操作有:

  • 拼接:用加号 + 可以合并两个或多个列表,形成一个新列表,不改变原列表。
  • 重复:用乘号 * 可以将列表重复多次,得到新列表。
  • 成员测试:使用 innot in 快速判断某个元素是否存在于列表中,结果为布尔值。
  • 获取长度len(lst) 得到列表中的元素数量。
# 连接列表
list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined = list1 + list2
print(combined) # [1, 2, 3, 4, 5, 6]

# 重复列表
repeated = list1 * 3
print(repeated) # [1, 2, 3, 1, 2, 3, 1, 2, 3]

# 检查元素是否存在
fruits = ["apple", "banana"]
print("apple" in fruits)  # True
print("orange" in fruits) # False

# 获取长度
print(len(fruits)) # 2

5.2.重要方法

  • append(x):在列表末尾添加一个元素 x
  • extend(iterable):把一个可迭代对象中的所有元素添加到当前列表。
  • insert(index, x):在指定位置插入元素 x
  • remove(x):删除第一个值等于 x 的元素。
  • pop([index]):删除并返回指定位置的元素(默认最后一个)。
  • clear():清空列表内所有元素。
  • index(x, [start, [end]]):在指定范围内查找第一个值等于 x 的元素,返回其索引。start 和 end 为可选参数,用于指定搜索范围。如果找不到则抛出 ValueError。
  • count(x):统计元素 x 在列表中出现的次数。
  • sort(key=None, reverse=False):对列表元素进行排序(原地排序,改变原列表)。
  • reverse():反转列表(原地操作)。
  • copy():返回列表的浅拷贝。
numbers = [3, 1, 4, 1, 5, 9, 2, 6]

# 排序 (会改变原列表)
numbers.sort()
print(numbers) # [1, 1, 2, 3, 4, 5, 6, 9]

# 反转 (会改变原列表)
numbers.reverse()
print(numbers) # [9, 6, 5, 4, 3, 2, 1, 1]

# 查找索引
print(numbers.index(5)) # 2 (返回第一个匹配的索引)

# 计数
print(numbers.count(1)) # 2 (元素1出现的次数)

# 复制列表 (创建新列表)
numbers_copy = numbers.copy()
# 等价于 numbers_copy = numbers[:]
# 等价于 numbers_copy = list(numbers)

6.列表遍历

6.1.直接遍历元素

直接遍历元素是最常见的列表遍历方式。例如,下面代码会依次将 fruits 列表中的每个元素赋值给变量 fruit 并执行循环体:

fruits = ["apple", "banana", "cherry"]

for fruit in fruits:
    print(f"I like {fruit}")

# 输出:
# I like apple
# I like banana
# I like cherry

这种方式适用于只关心元素本身、不需要索引的场景。

6.2.遍历索引和元素

使用 enumerate 可以在遍历列表时同时获得每个元素的索引和值。这在需要知道元素位于列表中哪个位置时非常有用。例如:

fruits = ["apple", "banana", "cherry"]

for index, fruit in enumerate(fruits):
    print(f"Index {index}: {fruit}")

# 输出:
# Index 0: apple
# Index 1: banana
# Index 2: cherry

其中,index 是当前元素的索引,fruit 是对应的值。

6.3.列表推导式

列表推导式(List Comprehensions)是 Python 提供的一种简洁优雅的构造新列表的方法。它既可以替代传统的 for 循环,也可以在创建列表时加入条件判断,让表达更加简明。

6.3.1.基本语法

new_list = [表达式 for 变量 in 可迭代对象]

相当于:

new_list = []
for 变量 in 可迭代对象:
    new_list.append(表达式)

6.3.2.带条件的列表推导式

还可以在推导式中添加条件:

new_list = [表达式 for 变量 in 可迭代对象 if 条件]

这样只有满足条件的元素才会加入新列表。

6.3.3.示例

  • 生成数字平方的列表:
nums = [1, 2, 3, 4]
squares = [x**2 for x in nums]  # [1, 4, 9, 16]
  • 过滤出偶数的平方:
squares_even = [x**2 for x in nums if x % 2 == 0]  # [4, 16]
  • 处理字符串:
fruits = ["Apple", "Banana", "cherry"]
lower_fruits = [f.lower() for f in fruits]  # ['apple', 'banana', 'cherry']

列表推导式常用来构建、转换、筛选列表,使代码更为简洁、易读。

# 传统方式:创建一个平方数列表
squares = []
for x in range(5):
    squares.append(x ** 2)
print(squares) # [0, 1, 4, 9, 16]

# 使用列表推导式(更简洁)
squares = [x ** 2 for x in range(5)]
print(squares) # [0, 1, 4, 9, 16]

# 带条件的列表推导式
even_squares = [x ** 2 for x in range(10) if x % 2 == 0]
print(even_squares) # [0, 4, 16, 36, 64]

7.多维列表(列表的列表)

列表可以包含其他列表,形成多维结构。

# 2x3 矩阵(二维列表)
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 访问元素
print(matrix[0])     # [1, 2, 3] - 第一行
print(matrix[1][2])  # 6 - 第二行第三列

# 遍历二维列表
for row in matrix:
    for element in row:
        print(element, end=" ")
    print() # 换行

# 输出:
# 1 2 3 
# 4 5 6 
# 7 8 9

8.重要注意事项

8.1.1. 浅拷贝 vs 深拷贝

浅拷贝(shallow copy)和深拷贝(deep copy)是列表复制时的两个概念,尤其是在涉及多维列表(嵌套列表)时需要特别注意。

  • 浅拷贝:只复制最外层的列表对象,内部的子对象依然引用原来的地址。常用 list.copy()切片[:]list() 实现。
  • 深拷贝:不仅复制最外层列表,也递归复制所有子对象,互不影响。需要用 copy.deepcopy()(需 import copy)。

例如:

# 浅拷贝
a = [[1, 2], [3, 4]]
b = a.copy()  # 只复制最外层
b[0][0] = 99
print(a)  # [[99, 2], [3, 4]],原列表被影响

# 深拷贝
import copy
a = [[1, 2], [3, 4]]
b = copy.deepcopy(a)
b[0][0] = 88
print(a)  # [[1, 2], [3, 4]],原列表不变
print(b)  # [[88, 2], [3, 4]]

所以:

  • 如果只是简单列表,浅拷贝足矣。
  • 如果是嵌套复杂结构,且需要完全独立的副本,务必使用深拷贝。
# 浅拷贝问题
original = [[1, 2], [3, 4]]
shallow_copy = original.copy()

# 修改浅拷贝中的子列表会影响原列表
shallow_copy[0][0] = 99
print(original)    # [[99, 2], [3, 4]] - 原列表也被改了!
print(shallow_copy) # [[99, 2], [3, 4]]

# 深拷贝解决方案
import copy
original = [[1, 2], [3, 4]]
deep_copy = copy.deepcopy(original)

deep_copy[0][0] = 99
print(original)  # [[1, 2], [3, 4]] - 原列表不受影响
print(deep_copy) # [[99, 2], [3, 4]]

8.2.列表 vs 元组

  • 列表:可变,用 []
  • 元组:不可变,用 ()
my_list = [1, 2, 3]  # 可以修改
my_tuple = (1, 2, 3) # 创建后不能修改

9.总结

操作类别方法/语法描述
创建[], list()创建列表
访问list[index], list[start:stop:step]索引和切片
修改list[index] = value直接赋值修改
添加append(), insert(), extend()添加元素
删除remove(), pop(), del, clear()删除元素
查询index(), count(), in查找元素
排序sort(), reverse()排序和反转
遍历for item in list, enumerate()循环遍历
高级列表推导式优雅创建新列表
img