深入了解Python enumerate和zip


Posted in Python onJuly 16, 2020

enumerate

首先介绍的是enumerate函数。

在我们日常编程的过程当中,经常会遇到一个问题。

在C语言以及一些古老的语言当中是没有迭代器这个概念的,所以我们要遍历数组或者是容器的时候,往往只能通过下标。有了迭代器之后,我们遍历的过程方便了很多,我们可以直接用一个变量去迭代一个容器当中的值。最简单的例子就是数组的遍历,比如我们要遍历items这个数组。我们可以直接:

for item in items:

通过迭代器的方式我们可以很轻松地遍历数组,而不再需要下标,也不需要计算数组的长度了。但是如果我们在循环体当中需要知道元素的下标该怎么办?

难道我们真的只能在下标和迭代器当中选择一个吗,比如在循环体的外面添加一个变量来记录下标?

idx = 0
for item in items:
  operation()
  idx += 1

这样可以解决问题,但是很麻烦,一点也不简洁,用专业的话来说一点也不pythonic(符合Python标准的代码)。为了追求pythonic,于是有了enumerate函数,来解决了我们又想直接迭代又需要知道元素下标的情形。

它的用法也很简单,我们把需要迭代的对象或者迭代器传入enumerate函数当中,它会为我们创建一个新的迭代器,同时返回下标以及迭代的内容。我们来看一个例子:

for i, item in enumerate(items):

除此之外,enumerate还支持传入参数。比如在某些场景当中,我们希望下标从1开始,而不再是0开始,我们可以额外多传入一个参数实现这点:

for i, item in enumerate(items, 1):

循环是我们编程的时候必不可少的操作,也正因此,enumerate函数使用非常广泛。但是有一点需要注意,如果我们迭代的是一个多元组数组,我们需要注意要将index和value区分开。举个例子:

data = [(1, 3), (2, 1), (3, 3)]

在不用enumerate的时候,我们有两种迭代方式,这两种都可以运行。

for x, y in data:

for (x, y) in data:

但是如果我们使用enumerate的话,由于引入了一个index,我们必须要做区分,否则会报错,所以我们只有一种迭代方式:

for i, (x, y) in enumerate(data):

zip

接下来要介绍的另一个函数同样是方便我们迭代的,不过它针对的是另一个场景——多对象迭代。

它的应用场景非常简单,就是我们想要同时迭代多份数据,比如用户的名字和用户的职业数据是分开的,我们希望同时遍历一个用户的职业和名字。如果不使用zip,我们可能只能放弃迭代器回到传统的下标遍历的模式了。这样当然是可以的,不过有两个小问题,第一个小问题当然是代码的可读性变差了,不够pythonic,第二个问题是我们需要维护两个容器长度不一样的情况,会增加额外的代码。而使用zip,可以同时解决以上两个问题。

我们来看一个例子:

names = ['xiaoming', 'xiaohua', 'xiaohei', 'xiaoli']
jobs = ['coach', 'student', 'student', 'student', 'professor']

for name, job in zip(names, jobs):
 print(name, job)

最后输出的结果是人名和职业的tuple:

xiaoming coach
xiaohua student
xiaohei student
xiaoli student

上面举的例子当中,names和jobs的长度其实是不一致的,在使用了zip的情况下,会自动替我们按照其中较短的那个进行截断。如果我们不希望截断,我们也可以使用itertools下的zip_longest来代替zip:

from itertools import zip_longest
for name, job in zip_longest(names, jobs):

这样的话长度不够的元素会以None来填充,zip_longest提供了一个参数fillvalue,可以填充成我们指定的值。

无论是zip还是zip_longest,都可以支持多迭代器的遍历。比如:

names = ['xiaoming', 'xiaohua', 'xiaohei', 'xiaoli']
jobs = ['coach', 'student', 'student', 'student', 'professor']
hobbies = ['footbal', 'tennis', 'badminton', 'basketbal']

for name, job, hobby in zip(names, jobs, hobbies):
 print(name, job, hobby)

zip除了方便我们迭代遍历之外,另一个很大的用处是可以很方便地生成dict。比如刚才的例子当中,我们想生成一个名称和职业的dict,一般的办法当然是先定义一个dict,然后遍历所有的key和value,来生成dict。然而使用zip,我们可以将这个操作简化到一行代码:

jobDict = dict(zip(names, jobs))

需要注意的是,我们调用zip返回的结果其实是一个迭代器,我们在转化成dict的时候自动遍历了迭代器当中的内容。比如我们如果直接打印出zip调用结果的话,就会发现屏幕上输出的是一个迭代器的地址:

print(zip(names, jobs))
>>> <zip object at 0x10ec93b40>

我们想要获得它的内容,需要将它手动转成list:

print(list(zip(names, jobs)))
>>> [('xiaoming', 'coach'), ('xiaohua', 'student'), ('xiaohei', 'student'), ('xiaoli', 'student')]

无论是enumerate还是zip其实底层都是基于迭代器实现的,从原理上来说并没有什么太深奥的内容,而且我们不使用它们也不影响我们写代码。但是Python之所以是Python,之所以很多人称道它简洁的语言和逻辑,离不开我们广泛地使用这些简化代码逻辑的工具和方法。因此我们加以了解是非常有必要的,希望大家都能写出pythonic的代码,不仅写代码能力强,而且代码本身也漂亮。

以上就是深入了解Python enumerate和zip的详细内容,更多关于Python enumerate和zip的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
在Django的模型中添加自定义方法的示例
Jul 21 Python
Python利用正则表达式匹配并截取指定子串及去重的方法
Jul 30 Python
深入解析Python中的__builtins__内建对象
Jun 21 Python
window下eclipse安装python插件教程
Apr 24 Python
Python常用内置模块之xml模块(详解)
May 23 Python
python邮件发送smtplib使用详解
Jun 16 Python
tensorflow实现加载mnist数据集
Sep 08 Python
widows下安装pycurl并利用pycurl请求https地址的方法
Oct 15 Python
PyQt5实现让QScrollArea支持鼠标拖动的操作方法
Jun 19 Python
python设置环境变量的原因和方法
Jun 24 Python
python被修饰的函数消失问题解决(基于wraps函数)
Nov 04 Python
使用py-spy解决scrapy卡死的问题方法
Sep 29 Python
详细分析Python collections工具库
Jul 16 #Python
带你学习Python如何实现回归树模型
Jul 16 #Python
MATLAB数学建模之画图汇总
Jul 16 #Python
浅析Python迭代器的高级用法
Jul 16 #Python
python 使用递归的方式实现语义图片分割功能
Jul 16 #Python
Django serializer优化类视图的实现示例
Jul 16 #Python
python中plt.imshow与cv2.imshow显示颜色问题
Jul 16 #Python
You might like
Smarty模板快速入门
2007/01/04 PHP
php下实现在指定目录搜索指定类型文件的函数
2008/10/03 PHP
关于mysql字符集设置了character_set_client=binary 在gbk情况下会出现表描述是乱码的情况
2013/01/06 PHP
php使用反射插入对象示例分享
2014/03/11 PHP
在PHP站点的页面上添加Facebook评论插件的实例教程
2016/01/08 PHP
thinkphp框架表单数组实现图片批量上传功能示例
2020/04/04 PHP
javascript 实现父窗口引用弹出窗口的值的脚本
2007/08/07 Javascript
jQuery 入门级学习笔记及源码
2010/01/22 Javascript
jquery获取下拉列表的值为null的解决方法
2011/03/18 Javascript
jquery 与NVelocity 产生冲突的解决方法
2011/06/13 Javascript
getJSON调用后台json数据时函数被调用两次的原因猜想
2013/09/29 Javascript
IE下支持文本框和密码框placeholder效果的JQuery插件分享
2015/01/31 Javascript
javascript通过元素id和name直接取得元素的方法
2015/04/28 Javascript
jQuery实现的左右移动焦点图效果
2016/01/14 Javascript
node实现定时发送邮件的示例代码
2017/08/26 Javascript
js实现rem自动匹配计算font-size的示例
2017/11/18 Javascript
vue组件中使用props传递数据的实例详解
2018/04/08 Javascript
ES6 Promise对象概念及用法实例详解
2019/10/15 Javascript
javascript实现简单搜索功能
2020/03/26 Javascript
JS原型对象操作实例分析
2020/06/06 Javascript
Python实现的二维码生成小软件
2014/07/11 Python
零基础学Python(一)Python环境安装
2014/08/20 Python
Python+Socket实现基于UDP协议的局域网广播功能示例
2017/08/31 Python
numpy返回array中元素的index方法
2018/06/27 Python
Python中垃圾回收和del语句详解
2018/11/15 Python
Python实现合并两个有序链表的方法示例
2019/01/31 Python
Selenium执行完毕未关闭chromedriver/geckodriver进程的解决办法(java版+python版)
2020/12/07 Python
HTML5 video视频字幕的使用和制作方法
2018/05/03 HTML / CSS
3种方式实现瀑布流布局小结
2019/09/05 HTML / CSS
美国在线精品家居网站:Burke Decor
2017/04/12 全球购物
纽约州一群才华横溢的金匠制作而成:Hearth Jewelry
2019/03/22 全球购物
槐乡的孩子教学反思
2014/04/27 职场文书
党员反邪教心得体会
2016/01/15 职场文书
python实现高效的遗传算法
2021/04/07 Python
python操作xlsx格式文件并读取
2021/06/02 Python
教你使用Python获取QQ音乐某个歌手的歌单
2022/04/03 Python