Python 3 教程

Python3 列表

在 Python 3 中,列表(List) 是最常用、最灵活的数据结构。它相当于其他语言中的“动态数组”,但功能更强大。

列表的核心特征是:有序、可变(Mutable)、允许重复元素、可以存储不同类型的数据

下面我将从基础操作核心切片技巧高效推导式常见陷阱,为你全面解析 Python 3 列表。


一、 创建与初始化

纯文本
plaintext
# 1. 空列表
empty_list = []
empty_list_2 = list()

# 2. 包含元素的列表
fruits = ["apple", "banana", "cherry"]

# 3. 混合类型 (Python 允许,但不推荐用于复杂逻辑)
mixed = [1, "hello", 3.14, True]

# 4. 快速生成列表
zeros = [0] * 5          # [0, 0, 0, 0, 0]
range_list = list(range(5)) # [0, 1, 2, 3, 4]

二、 增删改查 (CRUD)

1. 查 (Access)

支持正向索引和反向索引。

纯文本
plaintext
nums = [10, 20, 30, 40, 50]
print(nums[0])   # 10 (第一个)
print(nums[-1])  # 50 (最后一个)
# print(nums[10]) # ❌ IndexError: list index out of range

2. 改 (Update)

直接通过索引赋值。

纯文本
plaintext
nums[1] = 99
print(nums)  # [10, 99, 30, 40, 50]

3. 增 (Add)

  • append(): 尾部添加单个元素 (O(1),最快)。
  • insert(): 指定位置插入 (O(n),较慢,因为要移动后续元素)。
  • extend(): 批量追加另一个可迭代对象。
纯文本
plaintext
nums.append(60)       # [10, 99, 30, 40, 50, 60]
nums.insert(0, 5)     # [5, 10, 99, 30, 40, 50, 60]
nums.extend([70, 80]) # [5, 10, ..., 60, 70, 80]

4. 删 (Remove)

  • pop(): 弹出并返回指定索引的元素(默认最后一个)。
  • remove(): 删除第一个匹配值的元素。
  • del: 根据索引或切片删除。
  • clear(): 清空列表。
纯文本
plaintext
last = nums.pop()     # 删除并返回 80
nums.remove(99)       # 删除值为 99 的元素
del nums[0]           # 删除第一个元素

三、 灵魂技巧:切片 (Slicing) 🌟

切片是 Python 列表最强大的功能之一,语法为 list[start:stop:step]

  • 左闭右开:包含 start,不包含 stop
  • 步长:默认为 1。
纯文本
plaintext
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(nums[2:5])    # [2, 3, 4] (索引 2 到 4)
print(nums[:3])     # [0, 1, 2] (从头开始)
print(nums[7:])     # [7, 8, 9] (直到结尾)
print(nums[::2])    # [0, 2, 4, 6, 8] (每隔一个取一个)
print(nums[::-1])   # [9, 8, ..., 0] (🔥 经典用法:列表反转)

💡 注意:切片操作返回的是原列表的一个浅拷贝(Shallow Copy),修改切片结果不会影响原列表。


四、 现代 Python 利器:列表推导式 (List Comprehension)

这是区分新手和高手的关键。当需要根据旧列表生成新列表时,永远优先使用推导式,它比传统的 for 循环 + append 更快、更简洁。

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

纯文本
plaintext
# 场景 1:生成 0-9 的平方
squares = [x**2 for x in range(10)]
# 等价于:
# squares = []
# for x in range(10):
#     squares.append(x**2)

# 场景 2:过滤偶数并转换为字符串
evens_str = [str(x) for x in range(10) if x % 2 == 0]
# 输出: ['0', '2', '4', '6', '8']

# 场景 3:嵌套循环 (生成坐标点)
points = [(x, y) for x in range(2) for y in range(2)]
# 输出: [(0, 0), (0, 1), (1, 0), (1, 1)]

五、 常用内置函数与方法

方法/函数作用时间复杂度
len(list)获取长度O(1)
list.sort()原地排序 (修改原列表)O(n log n)
sorted(list)返回的排序列表 (不修改原列表)O(n log n)
list.reverse()原地反转O(n)
list.index(val)查找值第一次出现的索引O(n)
list.count(val)统计值出现的次数O(n)
val in list判断值是否存在O(n) (慢!见下文陷阱)

六、 ⚠️ 三大常见陷阱 (避坑指南)

陷阱 1:浅拷贝与引用问题

当你使用 = 赋值列表时,只是复制了引用(指针),而不是复制数据。修改其中一个,另一个也会变。

纯文本
plaintext
a = [1, 2, 3]
b = a          # b 指向同一个内存地址
b.append(4)
print(a)       # [1, 2, 3, 4] 😱 a 也被改变了!

# ✅ 正确拷贝方式:
c = a[:]       # 切片拷贝
d = a.copy()   # 方法拷贝
e = list(a)    # 构造函数拷贝

(注:如果列表中包含嵌套列表,以上方法均为浅拷贝,需使用 copy.deepcopy())

陷阱 2:在遍历列表时删除元素

这会导致索引错乱,跳过某些元素。

纯文本
plaintext
nums = [1, 2, 2, 3, 4]

# ❌ 错误做法
for n in nums:
    if n == 2:
        nums.remove(n) 
# 结果可能不符合预期,因为列表长度在变化

# ✅ 正确做法 1:列表推导式 (推荐)
nums = [n for n in nums if n != 2]

# ✅ 正确做法 2:倒序遍历
for i in range(len(nums)-1, -1, -1):
    if nums[i] == 2:
        del nums[i]

陷阱 3:误用 in 进行大量查找

if x in my_list 的时间复杂度是 O(n)。如果列表很大且需要频繁查找,请将其转换为 集合 (set),查找速度将提升至 O(1)

纯文本
plaintext
# 慢
if target in huge_list: ...

# 快
huge_set = set(huge_list)
if target in huge_set: ...

七、 总结:列表 vs 其他结构

  • 需要有序频繁修改? 👉 List
  • 需要快速查找是否存在? 👉 Set
  • 需要键值对映射? 👉 Dict
  • 数据不可变且作为字典 Key? 👉 Tuple

列表是 Python 的基石。掌握切片推导式,你就掌握了 Python 列表的精髓。

你想看一个具体的实战例子吗?比如:如何用一行代码实现矩阵转置,或者如何高效合并两个有序列表?随时告诉我!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注