查看: 132|回复: 3

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

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
在Python开发中,列表(list)、元组(tuple)、字典(dict)和集合(set)是最常用的可迭代对象。虽然它们都支持for...in循环,但由于底层数据结构不同(序列、映射、哈希表),遍历方式各有特点。本文从基础到深入,系统梳理遍历这些数据结构的常见方法,并重点剖析集合的底层原理与性能优势。
  1. 基础遍历模式:所有可迭代对象都适用for...in循环,但根据需求不同,有多种变体写法。
复制代码

一、遍历列表(List)与元组(Tuple)
列表和元组都是有序序列,元组不可变但遍历语法完全一致。
  1. lst = ['a', 'b', 'c']
  2. # 1. 直接遍历元素(最常用)
  3. for item in lst:
  4.     print(item)
  5. # 2. 通过索引遍历(range+长度)
  6. for i in range(len(lst)):
  7.     print(f"索引{i}: {lst[i]}")
  8. # 3. 同时获取索引和元素(enumerate,Pythonic推荐)
  9. for index, value in enumerate(lst):
  10.     print(f"第{index}个元素是{value}")
  11. # 可自定义起始序号
  12. for index, value in enumerate(lst, start=1):
  13.     print(f"第{index}个元素是{value}")
  14. # 4. 反向遍历(reversed,不修改原列表)
  15. for item in reversed(lst):
  16.     print(item)
  17. # 5. 并行遍历多个序列(zip)
  18. names = ['A', 'B']
  19. scores = [90, 85]
  20. for name, score in zip(names, scores):
  21.     print(f"{name}: {score}")
  22. # 6. 使用while循环(通用,但不推荐单纯遍历)
  23. i = 0
  24. while i < len(lst):
  25.     print(lst[i])
  26.     i += 1
复制代码

二、遍历字典(Dict)
字典是键值对映射,Python 3.7+保证插入顺序。
  1. d = {'name': 'Tom', 'age': 18}
  2. # 1. 默认遍历键(等效于d.keys())
  3. for key in d:
  4.     print(key)
  5. # 2. 遍历值
  6. for value in d.values():
  7.     print(value)
  8. # 3. 同时遍历键和值(最常用)
  9. for key, value in d.items():
  10.     print(f"{key} -> {value}")
  11. # 4. 遍历时修改字典(需转为列表避免RuntimeError)
  12. # 错误:for k in d: del d[k]  # RuntimeError
  13. # 正确做法:
  14. for k in list(d.keys()):
  15.     if k == 'age':
  16.         del d[k]
复制代码

三、遍历集合(Set)——基础篇
集合是无序、元素唯一的哈希表,遍历时不保证输出顺序。
  1. s = {1, 2, 3, 'a'}
  2. # 1. 标准for循环
  3. for item in s:
  4.     print(item)  # 顺序可能每次不同
  5. # 2. 使用enumerate获取人为序号(仅表示遍历次序)
  6. for idx, item in enumerate(s):
  7.     print(f"第{idx}个取出的元素是: {item}")
  8. # 3. 使用迭代器(iter和next)手动控制
  9. it = iter(s)
  10. while True:
  11.     try:
  12.         item = next(it)
  13.         print(item)
  14.     except StopIteration:
  15.         break
  16. # 4. 集合推导式(遍历并生成新集合)
  17. new_set = {x*2 for x in s if isinstance(x, int)}
复制代码
注意:集合不支持索引(s[0])和切片,无法通过range(len(s))按位置遍历。

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

1. 创建集合的陷阱
  1. a = {}    # 这是空字典,不是集合!
  2. b = set() # 正确的空集合
  3. c = {1, 2, 3} # 非空集合
复制代码

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

3. 集合数学运算(高频考点,性能极高)
  1. A = {1, 2, 3}
  2. B = {3, 4, 5}
  3. print(A | B)  # {1, 2, 3, 4, 5} 并集,相当于A.union(B)
  4. print(A & B)  # {3} 交集,相当于A.intersection(B)
  5. print(A - B)  # {1, 2} 差集,相当于A.difference(B)
  6. print(A ^ B)  # {1, 2, 4, 5} 对称差集,相当于A.symmetric_difference(B)
  7. print(A <= B) # False 子集判断,相当于A.issubset(B)
  8. print(A.isdisjoint(B)) # False 判断是否不相交
复制代码

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

5. 不可变集合——frozenset
业务中可能需要将集合作为字典的键或另一个集合的元素,但普通集合可变不可哈希。frozenset是集合的不可变版本,可哈希。
  1. fs = frozenset([1, 2, 3])
  2. d = {fs: "value"}  # 合法
复制代码

6. 遍历集合时修改集合(同样不安全)
遍历中增删集合大小会报错。解决方案:遍历其副本。
  1. s = {1, 2, 3, 4}
  2. for item in list(s):  # 转换为列表副本
  3.     if item % 2 == 0:
  4.         s.remove(item)
  5. print(s)  # {1, 3}
复制代码

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

使用道具 举报

发表于 1 小时前 | 显示全部楼层

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

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

使用道具 举报

发表于 1 小时前 | 显示全部楼层

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

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

使用道具 举报

发表于 1 小时前 | 显示全部楼层

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

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

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-3 10:36 , Processed in 0.038079 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部