Python 的 enumerate() 函数就像是一个神秘的黑箱,你无法简单地用一句话来概括这个函数的作用与用法。

enumerate() 函数属于非常有用的高级用法,而对于这一点,很多初学者甚至中级学者都没有意识到。这个函数的基本应用就是用来遍历一个集合对象,它在遍历的同时还可以得到当前元素的索引位置。

我们看一个例子:

names = ["Alice","Bob","Carl"]
for index,value in enumerate(names):
print(f'{index}: {value}')

这段代码会输入如下内容:

0: Alice
1: Bob
2: Carl

正如你所看到的,这个循环遍历了names列表的所有元素,并通过增加从零开始的计数器变量来为每个元素生成索引。

[如果您想知道上面例子中使用的f'...'字符串语法,这是Python 3.6及更高版本中提供的一种新的字符串格式化技巧。]

enumerate()让你的循环更加Python化

那么为什么用enumerate()函数去保存运行中的索引很有用呢?

我发现,有很多从C或Java背景转过来的新的Python开发人员有时使用下面这种range(len(...))方法来保存运行中每个元素的索引,同时再用for循环遍历列表:

# 警告: 不建议这么写
for i in range(len(my_items)):
print(i, my_items[i])

通过巧妙地使用enumerate()函数,就像我在上面的“names”例子中写的那样,你可以使你的循环结构看起来更Pythonic和地道。

你不再需要在Python代码中专门去生成元素索引,而是将所有这些工作都交给enumerate()函数处理即可。这样,你的代码将更容易被阅读,而且减少写错代码的影响。(译者注:写的代码越多,出错几率越高,尽量将自己的代码看起来简洁,易读,Pythonic,才是我们的追求)

修改起始索引

另一个有用的特性是,enumerate()函数允许我们为循环自定义起始索引值。enumerate()函数中接受一个可选参数,该参数允许你为本次循环中的计数器变量设置初始值:

names = ["Alice","Bob","Carl"]
for index,value in enumerate(names,1):
print(f'{index}: {value}')

在上面的例子中,我将函数调用改为enumerate(names, 1),后面的参数1就是本次循环的起始索引,替换默认的0:

1: Alice
2: Bob
3: Carl

OK,这段代码演示的就是如何将Python的enumerate()函数默认0起始索引值修改为1(或者其他任何整形值,根据需求去设置不同值)

enumerate()背后是如何工作的

你可能想知道enumerate()函数背后是如何工作的。事实上他的部分魔法是通过Python迭代器来实现的。意思就是每个元素的索引是懒加载的(一个接一个,用的时候生成),这使得内存使用量很低并且保持这个结构运行很快。

请看如下代码:

>>> names = ['Alice', 'Bob', 'Carl']
>>> enumerate(names)
<enumerate object at 0x1057f4120>

在上面这个代码片段中,正如你所见,我使用了和前面一样的示例代码。但是,调用enumerate()函数并不会立即返回循环的结果,而只是在控制台中返回了一个enumerate对象。

正如你所看到的,这是一个“枚举对象”。它的确是一个迭代器。就像我说的,它会在循环请求时懒加载地输出每个元素。

为了验证,我们可以取出那些“懒加载”的元素,我计划在这个迭代器上调用Python的内置函数list()。

>>> list(enumerate(names))
[(0, 'Alice'), (1, 'Bob'), (2, 'Carl')]

对于输入list()中的每个enumerate()迭代器元素,迭代器会返回一个形式为(index,element)的元组作为list的元素。在典型的for-in循环中,你可以利用Python的数据结构解包功能来充分利用这一点特性:

for index, element in enumerate(iterable):
# ...

总结:Python中的enumerate函数 - 关键点

  • enumerate是Python的一个内置函数。你应该充分利用它通过循环迭代自动生成的索引变量。
  • 索引值默认从0开始,但也可以将其设置为任何整数。
  • enumerate函数是从2.3版本开始被添加到Python中的,详情见PEP279
  • Python的enumerate函数可以帮助你编写出更加Pythonic和地道的循环结构,避免使用笨重且容易出错的手动生成索引。
  • 为了充分利用enumerate的特性,一定要研究Python的迭代器和数据结构解包功能。

参考

Python学习笔记之Python的enumerate函数的更多相关文章

  1. Python学习笔记——常用的内置函数

    一.yield def EricReadlines(): seek = 0 while True: with open('D:/temp.txt','r') as f: f.seek(seek) da ...

  2. python 学习笔记 9 -- Python强大的自省简析

    1. 什么是自省? 自省就是自我评价.自我反省.自我批评.自我调控和自我教育,是孔子提出的一种自我道德修养的方法.他说:“见贤思齐焉,见不贤而内自省也.”(<论语·里仁>)当然,我们今天不 ...

  3. Python学习笔记(五)Python的切片和迭代

    切片 Python提供了切片操作符,可以对list.tuple.字符串进行截取操作. list中的切片应用 语法如下: >>> L = ['Michael', 'Sarah', 'T ...

  4. python 学习笔记一——Python安装和IDLE使用

    好吧,一直准备学点啥,前些日子也下好了一些python电子书,但之后又没影了.年龄大了,就是不爱学习了.那就现在开始吧. 安装python 3 Mac OS X会预装python 2,Linux的大多 ...

  5. python学习笔记(一):python简介和入门

    最近重新开始学习python,之前也自学过一段时间python,对python还算有点了解,本次重新认识python,也算当写一个小小的教程.一.什么是python?python是一种面向对象.解释型 ...

  6. python学习笔记之——python模块

    1.python模块 Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python ...

  7. Python学习笔记 - day12 - Python操作NoSQL

    NoSQL(非关系型数据库) NoSQL,指的是非关系型的数据库.NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称.用于超大规模数据的存储.(例如 ...

  8. python学习笔记(python简史)

    一.python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum) 目前python主要应用领域: ·云计算 ·WEB开发 ·科学运算.人工智能 ·系统运维 ·金融:量化交 ...

  9. python学习笔记(1)--python特点

    python诞生于复杂的信息系统时代,是计算机时代演进的一种选择. python的特点,通用语言,脚本语言,跨平台语言.这门语言可以用于普适的计算,不局限于某一类应用,通用性是它的最大特点.pytho ...

随机推荐

  1. 【BZOJ】3403: [Usaco2009 Open]Cow Line 直线上的牛(模拟)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3404 裸的双端队列.. #include <cstdio> #include <c ...

  2. 从头认识java-17.4 具体解释同步(2)-具体解释竞争条件

    这一章节我们来具体讨论一下竞争条件. 1.为什么会引起竞争条件? 因为操作缺失原子性. 2.什么是原子性? 所谓原子操作是指不会被线程调度机制打断的操作:这样的操作一旦開始,就一直运行到结束.中间不会 ...

  3. ASP.NET动态增加HTML元素的方法实例小结

    本文实例讲述了ASP.NET动态增加HTML元素的方法.分享给大家供大家参考,具体如下: 在使用asp.net进行web开发的时候页面中的<head></head>中的信息可以 ...

  4. Chem 3D模型的参数值更改方法

    在化学绘图软件ChemOffice 15.1中有个专门用于绘制三维结构的组件,就是Chem 3D.通过这个组件用户可以绘制3D模型并可以通过这个组件来计算一些化学数据.在使用Chem 3D组件过程中, ...

  5. python3----练习题(冒泡排序)

    冒泡,原理是临近的数字两两进行比较,按照从小到大的顺序进行交换,这样交换一次之后,最大的数字就被交换到了最后一位. li = [33, 2, 10, 1] for j in range(1, len( ...

  6. Eclipse Android 代码自己主动提示功能

    Eclipse Android 代码自己主动提示功能 Eclipse for android 实现代码自己主动提示智能提示功能.介绍 Eclipse for android 编辑器中实现两种主要文件 ...

  7. IOS学习笔记28—SQLite3第三方库之FMDB

    本文转载至 http://blog.csdn.net/happyrabbit456/article/details/11609451 SQLite是一种小型的轻量级的关系型数据库,在移动设备上使用是非 ...

  8. [cocos2dx] cocosdx编译工程那些事

    cocos compile -p android 上面这条命令可以将cocos2dx的工程编译出android apk,需要注意的是如果有新增的cpp文件,都需要在“CocosProject\proj ...

  9. Oracle是如何工作的?实例是如何响应用户请求?一条SQL的执行过程~

    Oracle 是如何工作的? Select id,name from t order by id ; – SQL 解析(查看语法是否错误,如果没有错误,分析语意,执行此语句的权限) – 执行计划(OR ...

  10. js对象转成用&拼接的请求参数(转)

    var parseParam=function(param, key){ var paramStr=""; if(param instanceof String||param in ...