Python的枚举enumerate学习

这个enumerate可以说是非常常用和强大的一个东西,值得单独盘点学习复习一下。

关键语法拆解

for i, (doc, meta, doc_id) in enumerate(zip(docs, metas, ids)):
    # 处理每个元素的代码
1️⃣ zip(docs, metas, ids)
  • 功能:将3个列表逐元素打包成元组
  • 示例
    docs   = ["doc1", "doc2"]
    metas  = [{"source": "pdf"}, {"source": "code"}]
    ids    = ["id1", "id2"]
    
    list(zip(docs, metas, ids)) 
    # 输出: [('doc1', {'source': 'pdf'}, 'id1'), 
    #        ('doc2', {'source': 'code'}, 'id2')]
    
2️⃣ enumerate(...)
  • 功能:为每个打包后的元组添加索引
  • 示例
    list(enumerate(["a", "b"])) 
    # 输出:[(0, 'a'), (1, 'b')]
    
    list(enumerate(zip(docs, metas, ids))) 
    # 输出:[(0, ('doc1', {'source': 'pdf'}, 'id1')),
    #        (1, ('doc2', {'source': 'code'}, 'id2'))]
    
3️⃣ i, (doc, meta, doc_id)
  • 功能:解包索引和元组
  • 解包过程示意
    # 原始数据格式
    (0, ('doc1', {'source': 'pdf'}, 'id1'))
    
    # 拆分为:
    i = 0
    doc = 'doc1'
    meta = {'source': 'pdf'}
    doc_id = 'id1'
    

设计思想

  1. 同步遍历(Synchronized Iteration)
    ✅ 确保相关性强的多个数据集(文档内容、元数据、ID)保持顺序一致地处理

  2. 信息完备性
    ✅ 通过索引 i 额外提供顺序信息,方便调试和日志记录

  3. 最小化内存占用
    zipenumerate 按需生成数据,而不一次性加载到内存(类似生成器)


常见应用场景

1. 数据集检查(结合索引定位问题)
for idx, (text, label) in enumerate(zip(texts, labels)):
    if len(text) < 10: 
        print(f"警告:第{idx}条文本过短 -> {text}")
2. 批量数据增强
augmented_images = []
for i, (img, bbox) in enumerate(zip(images, bboxes)):
    aug_img = random_crop(img)
    augmented_images.append(aug_img)
    print(f"已处理第{i}张图像")
3. 结构化日志输出
data = [
    {"name": "Alice", "age": 30},
    {"name": "Bob", "age": 25}
]

for i, (user, metadata) in enumerate(zip(users, extra_info)):
    print(f"用户 {i+1}: {user['name']} | 附加信息: {metadata}")
4. 多列表对齐验证(重要!)
# 检查三个列表长度是否一致
assert len(docs) == len(metas) == len(ids)

for i, (doc, meta, doc_id) in enumerate(zip(docs, metas, ids)):
    if not doc_id.startswith("pdf"):
        print(f"异常ID格式:索引 {i}, ID {doc_id}")

与纯索引遍历的对比

假设不用 enumerate(zip(...)),传统写法:

for i in range(len(docs)):
    doc = docs[i]
    meta = metas[i]
    doc_id = ids[i]
    # 处理...

优势对比:

方法优点缺点
enumerate(zip)代码简洁,自动处理多个列表各列表必须等长
索引遍历灵活控制,可处理不等长列表需要写更多索引操作,易错

高手技巧

1. 用 strict=True 强制列表等长(Python ≥3.10)
for i, (a, b) in enumerate(zip(list1, list2, strict=True)):
    # 如果 list1 和 list2 不等长,立即触发 ValueError
2. 处理不等长列表需求(itertools.zip_longest
from itertools import zip_longest

for i, (a, b) in enumerate(zip_longest(list1, list2, fillvalue="缺省值")):
    # 空缺位置自动填充 "缺省值"
3. 压缩多层数据(医学影像案例)

假设每个病例包含多个诊断维度的数据:

# 三维数据组织
patients = ["P001", "P002"]
images = [ ["scan1.png", "scan2.png"], ["scan3.png"] ]
diagnoses = [ [0.9, 0.1], [0.4] ]

for p_idx, (pid, img_group, diag_group) in enumerate(zip(patients, images, diagnoses)):
    for s_idx, (img_path, diag_score) in enumerate(zip(img_group, diag_group)):
        print(f"患者{p_idx}{s_idx}次扫描:{img_path} → 诊断置信度 {diag_score}")

通过理解这种遍历模式的强大之处,已经可以游刃有余地处理现实项目中复杂的多数据流场景! 🚀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Terrence Shen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值