列表是 Python 中最常用的可变序列类型,可以存储任意类型的元素,支持增删改查等操作。

一、列表的创建

1. 基本创建方式

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

# 带初始值的列表
numbers = [1, 2, 3, 4, 5]
fruits = ["苹果", "香蕉", "橘子"]
mixed = [1, "hello", 3.14, True]
nested = [[1, 2], [3, 4], [5, 6]]  # 嵌套列表

# 使用 list() 转换
chars = list("hello")        # ['h', 'e', 'l', 'l', 'o']
nums = list(range(5))        # [0, 1, 2, 3, 4]

2. 列表推导式

# 生成平方数列表
squares = [x**2 for x in range(10)]
print(squares)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 带条件的列表推导式
evens = [x for x in range(20) if x % 2 == 0]
print(evens)  # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 嵌套循环
pairs = [(x, y) for x in range(3) for y in range(2)]
print(pairs)  # [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]

二、访问列表元素

1. 索引访问

fruits = ["苹果", "香蕉", "橘子", "葡萄", "西瓜"]

# 正索引(从 0 开始)
print(fruits[0])   # 苹果
print(fruits[2])   # 橘子

# 负索引(从 -1 开始)
print(fruits[-1])  # 西瓜
print(fruits[-3])  # 橘子

# 修改元素
fruits[1] = "芒果"
print(fruits)  # ['苹果', '芒果', '橘子', '葡萄', '西瓜']

2. 切片操作

nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 基本切片 [start:end]
print(nums[2:5])     # [2, 3, 4](包含索引2,不包含5)
print(nums[:5])      # [0, 1, 2, 3, 4](从开头到索引4)
print(nums[5:])      # [5, 6, 7, 8, 9](从索引5到末尾)
print(nums[:])       # 整个列表的副本

# 步长切片 [start:end:step]
print(nums[::2])     # [0, 2, 4, 6, 8](偶数索引)
print(nums[1::2])    # [1, 3, 5, 7, 9](奇数索引)
print(nums[::-1])    # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0](反转)

# 修改切片
nums[2:5] = [20, 30, 40]
print(nums)  # [0, 1, 20, 30, 40, 5, 6, 7, 8, 9]

三、列表常用方法

1. 添加元素

fruits = ["苹果", "香蕉"]

# append():末尾添加
fruits.append("橘子")
print(fruits)  # ['苹果', '香蕉', '橘子']

# insert():指定位置插入
fruits.insert(1, "芒果")
print(fruits)  # ['苹果', '芒果', '香蕉', '橘子']

# extend():扩展列表(合并另一个列表)
fruits.extend(["葡萄", "西瓜"])
print(fruits)  # ['苹果', '芒果', '香蕉', '橘子', '葡萄', '西瓜']

# 使用 + 运算符(返回新列表)
new_fruits = fruits + ["草莓", "蓝莓"]
print(new_fruits)  # 原列表不变,返回新列表

2. 删除元素

fruits = ["苹果", "香蕉", "橘子", "葡萄", "西瓜"]

# remove():删除指定值的元素(只删除第一个)
fruits.remove("香蕉")
print(fruits)  # ['苹果', '橘子', '葡萄', '西瓜']

# pop():删除指定索引的元素(默认删除最后一个)
removed = fruits.pop(1)
print(removed)  # 橘子
print(fruits)   # ['苹果', '葡萄', '西瓜']

removed_last = fruits.pop()
print(removed_last)  # 西瓜
print(fruits)        # ['苹果', '葡萄']

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

# del 语句
nums = [1, 2, 3, 4, 5]
del nums[2]        # 删除索引2的元素
print(nums)        # [1, 2, 4, 5]

del nums[1:3]      # 删除切片
print(nums)        # [1, 5]

del nums           # 删除整个列表变量
# print(nums)      # 错误!列表已被删除

3. 查找元素

fruits = ["苹果", "香蕉", "橘子", "香蕉", "葡萄"]

# index():返回元素的索引(只返回第一个)
print(fruits.index("香蕉"))     # 1
# print(fruits.index("榴莲"))   # ValueError

# count():统计元素出现的次数
print(fruits.count("香蕉"))     # 2
print(fruits.count("榴莲"))     # 0

# in 运算符:判断元素是否存在
print("苹果" in fruits)   # True
print("榴莲" in fruits)   # False

# not in 运算符
print("榴莲" not in fruits)  # True

4. 排序和反转

numbers = [3, 1, 4, 1, 5, 9, 2, 6]

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

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

# sorted():返回新列表,不修改原列表
numbers = [3, 1, 4, 1, 5]
sorted_nums = sorted(numbers)
print(sorted_nums)   # [1, 1, 3, 4, 5]
print(numbers)       # [3, 1, 4, 1, 5](原列表不变)

sorted_desc = sorted(numbers, reverse=True)
print(sorted_desc)   # [5, 4, 3, 1, 1]

# reverse():反转列表(原地修改)
numbers.reverse()
print(numbers)  # [5, 1, 4, 1, 3]

5. 其他方法

# len():获取列表长度
fruits = ["苹果", "香蕉", "橘子"]
print(len(fruits))  # 3

# copy():浅拷贝
fruits2 = fruits.copy()
print(fruits2)  # ['苹果', '香蕉', '橘子']

# 使用 list() 构造函数拷贝
fruits3 = list(fruits)

# 切片拷贝(最常用)
fruits4 = fruits[:]

# max() / min():最大最小值
numbers = [3, 1, 4, 1, 5, 9, 2]
print(max(numbers))  # 9
print(min(numbers))  # 1

# sum():求和
print(sum(numbers))  # 25

四、列表的遍历

1. 基本遍历

fruits = ["苹果", "香蕉", "橘子"]

# 遍历元素
for fruit in fruits:
    print(fruit)

# 遍历索引
for i in range(len(fruits)):
    print(f"{i}: {fruits[i]}")

# 同时遍历索引和元素(推荐)
for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")

# 指定起始索引
for i, fruit in enumerate(fruits, start=1):
    print(f"{i}: {fruit}")

2. 并行遍历多个列表

names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["北京", "上海", "广州"]

# 使用 zip()
for name, age, city in zip(names, ages, cities):
    print(f"{name}, {age}岁, 来自{city}")

# 不等长时使用 zip_longest
from itertools import zip_longest
a = [1, 2, 3]
b = ['a', 'b']
for x, y in zip_longest(a, b, fillvalue=None):
    print(x, y)  # (1, 'a'), (2, 'b'), (3, None)

五、列表常用操作

1. 列表比较

# 比较规则:逐个元素比较
print([1, 2, 3] == [1, 2, 3])     # True
print([1, 2, 3] == [1, 2, 4])     # False

print([1, 2, 3] < [1, 2, 4])      # True
print([1, 2, 3] > [1, 2])         # True

2. 列表乘法

# 重复列表元素
zeros = [0] * 5
print(zeros)  # [0, 0, 0, 0, 0]

matrix = [[0] * 3 for _ in range(3)]  # 创建二维列表
print(matrix)  # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

# 注意:不要用 [[0]*3]*3 这种方式(会创建引用相同的子列表)

3. 列表解包

# 基本解包
numbers = [1, 2, 3]
a, b, c = numbers
print(a, b, c)  # 1 2 3

# 使用 * 收集剩余元素
a, *rest = [1, 2, 3, 4, 5]
print(a)     # 1
print(rest)  # [2, 3, 4, 5]

first, *middle, last = [1, 2, 3, 4, 5]
print(first)   # 1
print(middle)  # [2, 3, 4]
print(last)    # 5

# 忽略元素
_, _, third, *_ = [1, 2, 3, 4, 5, 6]
print(third)  # 3

六、列表作为栈和队列

1. 栈(LIFO - 后进先出)

# 使用列表作为栈
stack = []

# 入栈(压入)
stack.append(1)
stack.append(2)
stack.append(3)
print(stack)  # [1, 2, 3]

# 出栈(弹出)
top = stack.pop()
print(top)     # 3
print(stack)   # [1, 2]

# 查看栈顶(不出栈)
print(stack[-1])  # 2

2. 队列(FIFO - 先进先出)

from collections import deque

# 使用 deque 实现队列
queue = deque()

# 入队
queue.append(1)
queue.append(2)
queue.append(3)

# 出队
first = queue.popleft()
print(first)   # 1
print(queue)   # deque([2, 3])

# 使用列表也可以,但效率较低
queue_list = []
queue_list.append(1)
queue_list.append(2)
queue_list.pop(0)  # 效率低,O(n)

七、深拷贝 vs 浅拷贝

import copy

# 浅拷贝:只拷贝外层,内层共享引用
original = [[1, 2], [3, 4]]
shallow = original.copy()

shallow[0][0] = 99
print(original)  # [[99, 2], [3, 4]](被修改了)

# 深拷贝:完全独立的副本
original = [[1, 2], [3, 4]]
deep = copy.deepcopy(original)

deep[0][0] = 99
print(original)  # [[1, 2], [3, 4]](不受影响)
print(deep)      # [[99, 2], [3, 4]]

八、总结表

操作 语法 时间复杂度
索引访问 lst[i] O(1)
追加 lst.append(x) O(1)
插入 lst.insert(i, x) O(n)
删除 lst.pop()(末尾) O(1)
删除 lst.pop(i)(任意位置) O(n)
查找 x in lst O(n)
切片 lst[i:j] O(k)
排序 lst.sort() O(n log n)

核心要点

  1. 列表是可变序列,可以修改元素

  2. 支持任意类型的混合存储

  3. 索引从 0 开始,支持负索引

  4. 切片创建新列表(浅拷贝)

  5. 列表推导式是高效的创建方式

  6. 注意浅拷贝深拷贝的区别

更多推荐