用 Python zip() 做并行迭代:用法、不等长处理与 strict 校验

难度:入门 · 来源:Real Python · 原文发布:2026-10-31

你将学到什么

  • 用 zip() 把多个可迭代对象按位置打包成元组,实现两个及以上序列的并行遍历。
  • 在输入长度不一致时做选择:默认按最短序列截断、用 itertools.zip_longest() 补值、或在 Python 3.10+ 用 strict=True 直接报错。
  • 理解 zip() 返回的是迭代器(惰性),以及用集合等无序容器时配对结果不确定的原因。

前置条件

  • 一个可运行 Python 3 的交互式环境(文中示例均在 REPL 中执行)。
  • 了解列表、元组、字典、集合、range() 等基本可迭代对象。
  • 使用 zip_longest() 时需从标准库 itertools 导入。

步骤

  1. 确认 zip() 是内置函数,无需 import。用 dir() 查看 __builtins__ 可以在列表末尾看到它:
>>> dir(__builtins__)
['ArithmeticError', 'AssertionError', 'AttributeError', ..., 'zip']
  1. 掌握基本用法:zip() 的签名是 zip(*iterables, strict=False),它返回一个迭代器而不是列表,需要 list() 消费后才能看到结果:
>>> numbers = [1, 2, 3]
>>> letters = ["a", "b", "c"]
>>> zipped = zip(numbers, letters)
>>> zipped
<zip object at 0x7fa4831153c8>
>>> list(zipped)
[(1, 'a'), (2, 'b'), (3, 'c')]
  1. 按需传入任意数量的可迭代对象,返回元组的长度等于传入参数个数:
>>> integers = [1, 2, 3]
>>> letters = ["a", "b", "c"]
>>> floats = [4.0, 5.0, 6.0]
>>> zipped = zip(integers, letters, floats)
>>> list(zipped)
[(1, 'a', 4.0), (2, 'b', 5.0), (3, 'c', 6.0)]
  1. 记住两个边界情况:只传一个参数时得到一系列单元素元组,不传参数时得到空迭代器:
>>> a = [1, 2, 3]
>>> list(zip(a))
[(1,), (2,), (3,)]
>>> list(zip())
[]

对空迭代器调用 next() 会抛出 StopIteration。

  1. 处理长度不一致的输入。默认行为是以最短的可迭代对象为准,较长序列的多余元素被静默忽略:
>>> list(zip(range(5), range(100)))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
  1. 如果尾部未配对的值不能丢,改用 itertools.zip_longest(),用 fillvalue 指定缺失位置的填充值(默认 None),迭代持续到最长序列耗尽:
>>> from itertools import zip_longest
>>> numbers = [1, 2, 3]
>>> letters = ["a", "b", "c"]
>>> longest = range(5)
>>> zipped = zip_longest(numbers, letters, longest, fillvalue="?")
>>> list(zipped)
[(1, 'a', 0), (2, 'b', 1), (3, 'c', 2), ('?', '?', 3), ('?', '?', 4)]
  1. 在 Python 3.10 及以上,把 strict 设为 True(PEP 618 引入)可在长度不相等时直接抛 ValueError,避免数据被静默丢弃;默认值 False 保持旧行为:
>>> list(zip(range(5), range(100), strict=True))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: zip() argument 2 is longer than argument 1
  1. 把 zip() 用到实际组合场景:原文还覆盖了并行遍历列表与字典、用解包运算符 * 把序列「解压」回原样(Python 没有单独的 unzip() 函数)、并行排序、成对计算,以及用 dict(zip()) 把两个序列的键值配对成字典。

常见坑/注意事项

  • zip() 是惰性的,返回迭代器;一旦被 list() 或循环消费完就空了,不能重复使用。
  • 传入集合这类无序容器时,元素顺序不固定,配对结果可能是「随机」的,不要依赖其顺序。
  • 长度不等时的默认截断会静默丢数据;对长度一致性有要求就用 strict=True,需要用尾部数据就换 zip_longest()。
  • 对空的 zip 迭代器调用 next() 会得到 StopIteration,遍历前最好先判断。
  • zip_longest() 的 fillvalue 默认为 None,需要可区分的占位符时要显式指定。

原文链接:https://realpython.com/python-zip-function/


原文:Using the Python zip() Function for Parallel Iteration(本文为采集智能体整理的导读,版权归原作者,请阅读原文获取完整内容)

← 导航里的「羊毛 / 优惠站」分类是什么用 Ollama 在 Claude Code 中启用子代理与联网搜索 →
AI技术网博主

独立开发者,记录 AI、开发与效率工具。

查看主页

评论(1)

aijishu554432026-11-05 13:27
建议给 API 调用加指数退避重试和超时。国内网络偶发超时常见,简单重试能解决大部分问题,不用上复杂方案。
登录后即可参与回复。立即登录 或 注册账号