脚本专家 发表于 2026-7-3 09:00:03

Python遍历列表、元组、字典、集合实战:8种遍历方法及集合深度解析

在Python开发中,列表(list)、元组(tuple)、字典(dict)和集合(set)是最常用的可迭代对象。虽然它们都支持for...in循环,但由于底层数据结构不同(序列、映射、哈希表),遍历方式各有特点。本文从基础到深入,系统梳理遍历这些数据结构的常见方法,并重点剖析集合的底层原理与性能优势。


基础遍历模式:所有可迭代对象都适用for...in循环,但根据需求不同,有多种变体写法。


一、遍历列表(List)与元组(Tuple)
列表和元组都是有序序列,元组不可变但遍历语法完全一致。

lst = ['a', 'b', 'c']
# 1. 直接遍历元素(最常用)
for item in lst:
    print(item)

# 2. 通过索引遍历(range+长度)
for i in range(len(lst)):
    print(f"索引{i}: {lst}")

# 3. 同时获取索引和元素(enumerate,Pythonic推荐)
for index, value in enumerate(lst):
    print(f"第{index}个元素是{value}")
# 可自定义起始序号
for index, value in enumerate(lst, start=1):
    print(f"第{index}个元素是{value}")

# 4. 反向遍历(reversed,不修改原列表)
for item in reversed(lst):
    print(item)

# 5. 并行遍历多个序列(zip)
names = ['A', 'B']
scores =
for name, score in zip(names, scores):
    print(f"{name}: {score}")

# 6. 使用while循环(通用,但不推荐单纯遍历)
i = 0
while i < len(lst):
    print(lst)
    i += 1


二、遍历字典(Dict)
字典是键值对映射,Python 3.7+保证插入顺序。

d = {'name': 'Tom', 'age': 18}
# 1. 默认遍历键(等效于d.keys())
for key in d:
    print(key)

# 2. 遍历值
for value in d.values():
    print(value)

# 3. 同时遍历键和值(最常用)
for key, value in d.items():
    print(f"{key} -> {value}")

# 4. 遍历时修改字典(需转为列表避免RuntimeError)
# 错误:for k in d: del d# RuntimeError
# 正确做法:
for k in list(d.keys()):
    if k == 'age':
      del d


三、遍历集合(Set)——基础篇
集合是无序、元素唯一的哈希表,遍历时不保证输出顺序。

s = {1, 2, 3, 'a'}
# 1. 标准for循环
for item in s:
    print(item)# 顺序可能每次不同

# 2. 使用enumerate获取人为序号(仅表示遍历次序)
for idx, item in enumerate(s):
    print(f"第{idx}个取出的元素是: {item}")

# 3. 使用迭代器(iter和next)手动控制
it = iter(s)
while True:
    try:
      item = next(it)
      print(item)
    except StopIteration:
      break

# 4. 集合推导式(遍历并生成新集合)
new_set = {x*2 for x in s if isinstance(x, int)}

注意:集合不支持索引(s)和切片,无法通过range(len(s))按位置遍历。

四、集合深度详解
集合基于哈希表实现,具有以下核心特性:
- 无序性:元素存放位置由哈希值决定,CPython 3.6+虽保留插入顺序但官方不保证,不应依赖。
- 唯一性:自动去重,两个相等的元素(==)只保留一个。
- 元素必须可哈希:只能放入不可变类型(int, str, tuple),放入list/dict/set会报TypeError: unhashable type。

1. 创建集合的陷阱

a = {}    # 这是空字典,不是集合!
b = set() # 正确的空集合
c = {1, 2, 3} # 非空集合


2. 核心增删改查方法

s = {1, 2, 3}
s.add(4)         # 添加元素,已存在无效果
s.update()# 批量添加(合并另一个可迭代对象)
s.remove(3)      # 删除元素,不存在则KeyError
s.discard(10)    # 删除元素,不存在不报错(推荐使用)
s.pop()          # 随机弹出一个元素,空集合调用报错
s.clear()      # 清空集合


3. 集合数学运算(高频考点,性能极高)

A = {1, 2, 3}
B = {3, 4, 5}
print(A | B)# {1, 2, 3, 4, 5} 并集,相当于A.union(B)
print(A & B)# {3} 交集,相当于A.intersection(B)
print(A - B)# {1, 2} 差集,相当于A.difference(B)
print(A ^ B)# {1, 2, 4, 5} 对称差集,相当于A.symmetric_difference(B)
print(A <= B) # False 子集判断,相当于A.issubset(B)
print(A.isdisjoint(B)) # False 判断是否不相交


4. 巨大的性能优势——成员检测
列表的if x in list时间复杂度O(n)(遍历查找),而集合的if x in set是O(1)(哈希直接命中)。实战中,若需频繁判断元素是否存在,应先将列表转为集合再操作。

5. 不可变集合——frozenset
业务中可能需要将集合作为字典的键或另一个集合的元素,但普通集合可变不可哈希。frozenset是集合的不可变版本,可哈希。

fs = frozenset()
d = {fs: "value"}# 合法


6. 遍历集合时修改集合(同样不安全)
遍历中增删集合大小会报错。解决方案:遍历其副本。

s = {1, 2, 3, 4}
for item in list(s):# 转换为列表副本
    if item % 2 == 0:
      s.remove(item)
print(s)# {1, 3}


总结对比:列表和元组遍历方式一致,有序、允许重复、可通过索引访问;字典有序(3.7+)、键唯一值可重复、按键名获取值;集合无序不可依赖、自动去重、不可索引。Python之禅说“扁平比嵌套更好”,遍历时尽量用for...in直接解包,少用range(len()),代码更具可读性。

热心网友5 发表于 2026-7-3 09:10:00

Re: Python遍历列表、元组、字典、集合实战:8种遍历方法及集合深度解析

感谢楼主的详细分享,干货满满!特别是集合的底层原理和性能对比,对日常写代码优化很有帮助。文中提到集合遍历时顺序不保证,这个坑之前踩过,后来改用`sorted()`临时排序才稳定。另外有个小问题想请教:对于超大列表(比如百万级)频繁做成员检测,转集合虽然O(1)但转换本身有开销,楼主一般是在初始化阶段就转好,还是在循环里临时转?有没有实际场景的推荐阈值?

热心网友5 发表于 2026-7-3 09:10:00

Re: Python遍历列表、元组、字典、集合实战:8种遍历方法及集合深度解析

感谢楼主的系统总结,非常实用!特别是集合那块,很多新手容易忽略空集合要用 `set()` 创建,以及 `frozenset` 作为字典键的使用场景。另外补充一个小点:遍历集合时如果想安全地删除元素,除了转为列表再删,也可以用 `copy()` 创建副本再遍历原集合,类似 `for item in s.copy()`,这样不会报 `RuntimeError`。楼主提到集合成员检测的 O(1) 优势,实际项目中我常用它来快速去重或做交集运算,效率确实高。

热心网友5 发表于 2026-7-3 09:10:00

Re: Python遍历列表、元组、字典、集合实战:8种遍历方法及集合深度解析

非常全面且实用的总结!特别是集合部分,把哈希表原理和性能优势讲得很清晰,对于经常做去重和成员判断的场景很有帮助。另外,楼主在文末提到的“遍历集合时修改集合(同样不安”好像没有写完,是同样不安全吗?确实,遍历集合时直接修改(比如add或remove)会引发RuntimeError,稳妥的做法是先转成list再操作。frozenset作为字典键的使用场景也很值得注意,比如缓存一组不可变的配置选项。感谢分享!
页: [1]
查看完整版本: Python遍历列表、元组、字典、集合实战:8种遍历方法及集合深度解析