《编写高质量Python代码的59个有效方法》——第11条:用zip函数同时遍历两个迭代器

简介:

本节书摘来自华章社区《编写高质量Python代码的59个有效方法》一书中的第11条:用zip函数同时遍历两个迭代器,作者[美]布雷特·斯拉特金(Brett Slatkin),更多章节内容可以访问云栖社区“华章社区”公众号查看

第11条:用zip函数同时遍历两个迭代器
在编写Python代码时,我们通常要面对很多列表,而这些列表里的对象,可能也是相互关联的。通过列表推导,很容易就能根据某个表达式从源列表推算出一份派生类表(参见本书第7条)。

对于本例中的派生列表和源列表来说,相同索引处的两个元素之间有着关联。如果想平行地迭代这两份列表,那么可以根据names源列表的长度来执行循环。

上面这段代码的问题在于,整个循环语句看上去很乱。用下标来访问names和letters会使代码不易阅读。用循环下标i来访问数组的写法一共出现了两次。改用enumerate来做(参见本书第10条)可以稍稍缓解这个问题,但仍然不够理想。

使用Python内置的zip函数,能够令上述代码变得更为简洁。在Python 3中的zip函数,可以把两个或两个以上的迭代器封装为生成器,以便稍后求值。这种zip生成器,会从每个迭代器中获取该迭代器的下一个值,然后把这些值汇聚成元组(tuple)。与通过下标来访问多份列表的那种写法相比,这种用zip写出来的代码更加明晰。

内置的zip函数有两个问题。
第一个问题是,Python 2中的zip并不是生成器,而是会把开发者所提供的那些迭代器,都平行地遍历一次,在此过程中,它都会把那些迭代器所产生的值汇聚成元组,并把那些元组所构成的列表完整地返回给调用者。这可能会占用大量内存并导致程序崩溃。如果要在Python 2里用zip来遍历数据量非常大的迭代器,那么应该使用itertools内置模块中的izip函数(参见本书第46条)。
第二个问题是,如果输入的迭代器长度不同,那么zip会表现出奇怪的行为。例如,我们又给names里添加了一个名字,但却忘了把这个名字的字母数量更新到letters之中。现在,如果用zip同时遍历这两份列表,那就会产生意外的结果。

新元素'Rosalind'并没有出现在遍历结果中。这正是zip的运作方式。受封装的那些迭代器中,只要有一个耗尽,zip就不再产生元组了。如果待遍历的迭代器长度都相同,那么这种运作方式不会出问题,由列表推导所推算出的派生列表一般都和源列表等长。如果待遍历的迭代器长度不同,那么zip会提前终止,这将会导致意外的结果。若不能确定zip所封装的列表是否等长,则可考虑改用itertools内置模块中的zip_longest函数(此函数在Python 2里叫做izip_longest)。
要点
内置的zip函数可以平行地遍历多个迭代器。
Python 3中的zip相当于生成器,会在遍历过程中逐次产生元组,而Python 2中的zip则是直接把这些元组完全生成好,并一次性地返回整份列表。
如果提供的迭代器长度不等,那么zip就会自动提前终止。
itertools内置模块中的zip_longest函数可以平行地遍历多个迭代器,而不用在乎它们的长度是否相等(参见本书第46条)。

相关文章
WK
|
12天前
|
Python
Python中format_map()方法
在Python中,`format_map()`方法用于使用字典格式化字符串。它接受一个字典作为参数,用字典中的键值对替换字符串中的占位符。此方法适用于从字典动态获取值的场景,尤其在处理大量替换值时更为清晰和方便。
WK
65 36
|
1天前
|
设计模式 缓存 监控
Python中的装饰器:代码的魔法增强剂
在Python编程中,装饰器是一种强大而灵活的工具,它允许程序员在不修改函数或方法源代码的情况下增加额外的功能。本文将探讨装饰器的定义、工作原理以及如何通过自定义和标准库中的装饰器来优化代码结构和提高开发效率。通过实例演示,我们将深入了解装饰器的应用,包括日志记录、性能测量、事务处理等常见场景。此外,我们还将讨论装饰器的高级用法,如带参数的装饰器和类装饰器,为读者提供全面的装饰器使用指南。
|
1天前
|
存储 算法 搜索推荐
Python高手必备!揭秘图(Graph)的N种风骚表示法,让你的代码瞬间高大上
在Python中,图作为重要的数据结构,广泛应用于社交网络分析、路径查找等领域。本文介绍四种图的表示方法:邻接矩阵、邻接表、边列表和邻接集。每种方法都有其特点和适用场景,掌握它们能提升代码效率和可读性,让你在项目中脱颖而出。
13 5
|
1天前
|
数据库 Python
异步编程不再难!Python asyncio库实战,让你的代码流畅如丝!
在编程中,随着应用复杂度的提升,对并发和异步处理的需求日益增长。Python的asyncio库通过async和await关键字,简化了异步编程,使其变得流畅高效。本文将通过实战示例,介绍异步编程的基本概念、如何使用asyncio编写异步代码以及处理多个异步任务的方法,帮助你掌握异步编程技巧,提高代码性能。
11 4
|
1天前
|
Python
不容错过!Python中图的精妙表示与高效遍历策略,提升你的编程艺术感
本文介绍了Python中图的表示方法及遍历策略。图可通过邻接表或邻接矩阵表示,前者节省空间适合稀疏图,后者便于检查连接但占用更多空间。文章详细展示了邻接表和邻接矩阵的实现,并讲解了深度优先搜索(DFS)和广度优先搜索(BFS)的遍历方法,帮助读者掌握图的基本操作和应用技巧。
13 4
|
3天前
|
缓存 开发者 Python
探索Python中的装饰器:简化和增强你的代码
【10月更文挑战第32天】 在编程的世界中,简洁和效率是永恒的追求。Python提供了一种强大工具——装饰器,它允许我们以声明式的方式修改函数的行为。本文将深入探讨装饰器的概念、用法及其在实际应用中的优势。通过实际代码示例,我们不仅理解装饰器的工作方式,还能学会如何自定义装饰器来满足特定需求。无论你是初学者还是有经验的开发者,这篇文章都将为你揭示装饰器的神秘面纱,并展示如何利用它们简化和增强你的代码库。
|
1天前
|
API 数据处理 Python
探秘Python并发新世界:asyncio库,让你的代码并发更优雅!
在Python编程中,随着网络应用和数据处理需求的增长,并发编程变得愈发重要。asyncio库作为Python 3.4及以上版本的标准库,以其简洁的API和强大的异步编程能力,成为提升性能和优化资源利用的关键工具。本文介绍了asyncio的基本概念、异步函数的定义与使用、并发控制和资源管理等核心功能,通过具体示例展示了如何高效地编写并发代码。
8 2
|
2天前
|
算法 Python
Python图论探索:从理论到实践,DFS与BFS遍历技巧让你秒变技术大牛
图论在数据结构与算法中占据重要地位,应用广泛。本文通过Python代码实现深度优先搜索(DFS)和广度优先搜索(BFS),帮助读者掌握图的遍历技巧。DFS沿路径深入搜索,BFS逐层向外扩展,两者各具优势。掌握这些技巧,为解决复杂问题打下坚实基础。
9 2
|
3天前
|
机器学习/深度学习 自然语言处理 API
如何使用阿里云的语音合成服务(TTS)将文本转换为语音?本文详细介绍了从注册账号、获取密钥到编写Python代码调用TTS服务的全过程
如何使用阿里云的语音合成服务(TTS)将文本转换为语音?本文详细介绍了从注册账号、获取密钥到编写Python代码调用TTS服务的全过程。通过简单的代码示例,展示如何将文本转换为自然流畅的语音,适用于有声阅读、智能客服等场景。
20 3
|
5天前
|
设计模式 缓存 测试技术
Python中的装饰器:功能增强与代码复用的艺术####
本文将深入探讨Python中装饰器的概念、用途及实现方式,通过实例演示其如何为函数或方法添加新功能而不影响原有代码结构,从而提升代码的可读性和可维护性。我们将从基础定义出发,逐步深入到高级应用,揭示装饰器在提高代码复用性方面的强大能力。 ####