Python 列表

列表(list)是 Python 最常用的数据结构,没有之一。它像一个可变长、有序、能放任何类型的容器,几乎所有 Python 程序都会用到。这一章把它彻底讲透——增删改查、切片、排序、列表推导式。

1. 什么是列表?

列表是一个有序、可变的序列,用方括号 [] 创建,元素之间用逗号分隔。可变意味着可以增删改,有序意味着元素有固定顺序、可以按下标访问。

# 列表:有序、可变的序列,用方括号 [] 创建
fruits = ["apple", "banana", "cherry"]
numbers = [10, 20, 30, 40, 50]
mixed = [1, "hello", True, 3.14, [1, 2]]   # 可以放任意类型,甚至嵌套

# 空列表
empty1 = []
empty2 = list()

# 用 list() 把其他序列转成列表
print(list("hello"))     # ['h', 'e', 'l', 'l', 'o']
print(list(range(5)))    # [0, 1, 2, 3, 4]

# 查看
print(fruits)            # ['apple', 'banana', 'cherry']
print(len(fruits))       # 3   长度

列表可以放任意类型的元素,甚至混合类型或嵌套列表——这点和 C/Java 的数组(必须同类型、定长)很不一样,更像是 JavaScript 的 Array。

2. 索引与切片

列表的索引、切片和字符串完全一样——因为它们都是"序列"类型。

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

# 1. 索引访问(和字符串一样)
print(fruits[0])         # apple      第一个
print(fruits[-1])        # elderberry  最后一个

# 2. 切片 [起:止:步长]
print(fruits[1:3])       # ['banana', 'cherry']
print(fruits[:2])        # ['apple', 'banana']
print(fruits[-2:])       # ['date', 'elderberry']  最后两个
print(fruits[::-1])      # 反转列表

# 3. 修改元素(列表可变!)
fruits[0] = "APPLE"
print(fruits)            # ['APPLE', 'banana', ...]

# 4. 判断包含
print("banana" in fruits)   # True
print("orange" in fruits)   # False

区别只是:列表可变,可以通过 list[i] = 新值 修改元素;字符串不行。

3. 添加元素:append / insert / extend

fruits = ["apple", "banana"]

# 1. append:末尾添加一个元素
fruits.append("cherry")
print(fruits)          # ['apple', 'banana', 'cherry']

# 2. insert:在指定位置插入
fruits.insert(0, "orange")      # 在开头插入
print(fruits)          # ['orange', 'apple', 'banana', 'cherry']

# 3. extend:把另一个列表的元素逐个加进来
more = ["grape", "kiwi"]
fruits.extend(more)
print(fruits)
# ['orange', 'apple', 'banana', 'cherry', 'grape', 'kiwi']

# ⚠ append vs 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]       把元素逐个加进来

# + 拼接(返回新列表,不改原列表)
c = [1, 2] + [3, 4]
print(c)               # [1, 2, 3, 4]

新手最容易混淆 appendextend。记住:append 把列表当一个整体加进去,extend 把元素逐个加进去

4. 删除元素:remove / pop / del / clear

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

# 1. remove:删除第一个匹配的值
fruits.remove("banana")
print(fruits)         # ['apple', 'cherry', 'banana', 'date']
# 如果元素不存在,会报 ValueError
# fruits.remove("orange")   # ❌ ValueError

# 2. pop:按索引删除,并返回被删的值
removed = fruits.pop(1)      # 删第 1 个,返回它
print(removed)        # cherry
print(fruits)         # ['apple', 'banana', 'date']

fruits.pop()          # 不传索引,删最后一个
print(fruits)         # ['apple', 'banana']

# 3. del 语句:按索引删除,不返回值
del fruits[0]
print(fruits)         # ['banana']

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

四种删除方式的区别:

5. 查找与统计

nums = [10, 20, 30, 20, 40, 20]

# 1. index:查找第一个匹配的下标,找不到报错
print(nums.index(30))      # 2
# nums.index(99)           # ❌ ValueError

# 2. count:统计元素出现次数
print(nums.count(20))      # 3

# 3. in / not in:判断包含
print(20 in nums)          # True
print(99 not in nums)      # True

# 4. len / max / min / sum
print(len(nums))           # 6
print(max(nums))           # 40
print(min(nums))           # 10
print(sum(nums))           # 140

6. 排序:sort() 与 sorted()

# 1. sort():原地排序(改原列表),返回 None
nums = [3, 1, 4, 1, 5, 9, 2, 6]
nums.sort()
print(nums)            # [1, 1, 2, 3, 4, 5, 6, 9]

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

# 2. sorted():返回新列表,不改原列表
nums2 = [3, 1, 4]
result = sorted(nums2)
print(nums2)           # [3, 1, 4]   原列表没变
print(result)          # [1, 3, 4]

# 3. 字符串排序(按字典序)
words = ["banana", "apple", "cherry"]
words.sort()
print(words)           # ['apple', 'banana', 'cherry']

# 4. 用 key 自定义排序规则
students = [("小明", 85), ("小红", 92), ("小刚", 78)]

# 按分数(元组第 2 项)排序
students.sort(key=lambda x: x[1])
print(students)
# [('小刚', 78), ('小明', 85), ('小红', 92)]

# 按分数降序
students.sort(key=lambda x: x[1], reverse=True)

# 5. reverse():原地反转(不是排序!)
x = [1, 3, 2]
x.reverse()
print(x)               # [2, 3, 1]

sort 和 sorted 的区别非常关键:

key 参数自定义排序规则时,lambda 函数(匿名函数,后面讲)极其好用。

7. 列表推导式(重点!Pythonic 之道)

列表推导式是 Python 最具特色的写法之一,一行就能从已有列表生成新列表,比 for 循环简洁、运行也更快。

# 列表推导式:list comprehension
# 经典 Pythonic 写法,一行生成新列表

# 1. 基本语法:[表达式 for 变量 in 序列]
nums = [1, 2, 3, 4, 5]
squares = [n * n for n in nums]
print(squares)         # [1, 4, 9, 16, 25]

# 2. 加条件过滤:[表达式 for 变量 in 序列 if 条件]
evens = [n for n in nums if n % 2 == 0]
print(evens)           # [2, 4]

# 3. 实用例子
# 把字符串列表全部转大写
names = ["alice", "bob", "charlie"]
upper_names = [name.upper() for name in names]
print(upper_names)     # ['ALICE', 'BOB', 'CHARLIE']

# 生成 1~10 的平方,只要偶数的
even_squares = [n*n for n in range(1, 11) if n % 2 == 0]
print(even_squares)    # [4, 16, 36, 64, 100]

# 4. 嵌套循环(可读性差,慎用)
pairs = [(i, j) for i in range(2) for j in range(2)]
print(pairs)           # [(0,0),(0,1),(1,0),(1,1)]

# 等价的 for 循环写法(对比理解)
squares = []
for n in nums:
    squares.append(n * n)

语法:[表达式 for 变量 in 序列 if 条件]。读法是"对序列里每个变量,如果满足条件,就生成表达式"。适度使用能提升可读性,但过度嵌套(三层以上)反而难懂,这时还是老老实实写 for 循环。

8. 浅拷贝与深拷贝(重要陷阱)

这是新手最容易踩的大坑:赋值不是复制

# ⚠ 列表是可变对象,赋值只是"贴标签",不是复制!
a = [1, 2, 3]
b = a                  # b 和 a 指向同一个列表
b.append(4)
print(a)               # [1, 2, 3, 4]   <- a 也变了!

# 浅拷贝(复制外层,内层还是共享)
c = a.copy()           # 等价写法:a[:] 或 list(a)
c.append(5)
print(a)               # [1, 2, 3, 4]   <- a 没变

# 但浅拷贝对嵌套列表不够用
nested = [[1, 2], [3, 4]]
shallow = nested.copy()
shallow[0].append(99)
print(nested)          # [[1, 2, 99], [3, 4]]   <- 内层列表还是共享!

# 深拷贝:用 copy.deepcopy,完全独立
import copy
deep = copy.deepcopy(nested)
deep[0].append(100)
print(nested)          # [[1, 2, 99], [3, 4]]   <- 这次彻底没变

记住:

9. 嵌套列表(二维数组)

# 嵌套列表(二维数组)
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 访问:matrix[行][列]
print(matrix[0][0])    # 1   第一行第一列
print(matrix[1][2])    # 6   第二行第三列
print(matrix[2])       # [7, 8, 9]  整行

# 遍历二维列表
for row in matrix:
    for cell in row:
        print(cell, end=" ")
    print()
# 输出:
# 1 2 3
# 4 5 6
# 7 8 9

处理表格、矩阵、棋盘等二维数据时,嵌套列表是标准做法。

小结

列表是 Python 最常用的数据结构。重点掌握:增删改查(append/insert/extend/remove/pop/del)、切片sort 与 sorted(原地 vs 返回新)、列表推导式(一行 Pythonic)、浅拷贝 vs 深拷贝(赋值不是复制!)。下一篇看列表的"亲兄弟"——元组。

← 上一篇 Python 字符串

下一篇 Python 元组

✈️💬