社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

揭秘 Python 中的 enumerate() 函数

编程派 • 6 年前 • 388 次点击  

译者:Vimiix 

作者:Dan Bader 

译文:http://vimiix.com/post/2017/12/13/Pythons-enumerate-Function-Demystified/

如何以去写以及为什么你应该使用Python中的内置枚举函数来编写更干净更加Pythonic的循环语句?

Python的 enumerate函数是一个神话般的存在,以至于它很难用一句话去总结它的目的和用处。

但是,它是一个非常有用的函数,许多初学者,甚至中级Pythonistas是并没有真正意识到。简单来说, enumerate()是用来遍历一个可迭代容器中的元素,同时通过一个计数器变量记录当前元素所对应的索引值。

让我们来看一个示例:

  1. names = ['Bob', 'Alice', 'Guido']

  2. for index, value in enumerate(names):

  3.    print(f'{index}: {value}')

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

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

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

用 enumerate()让你的循环更加Pythonic

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

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

  1. # 警告: 不建议这么写

  2. for i in range(len(my_items)):

  3.    print(i, my_items[i])

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

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

修改起始索引

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

  1. names = ['Bob', 'Alice', 'Guido']

  2. for index, value in enumerate(names, 1):

  3.    print (f'{index}: {value}')

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

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

enumerate()背后是如何工作的

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

让我们演示一些更多的代码来表达我的意思:

  1. >>> names = ['Bob', 'Alice', 'Guido']

  2. >>> enumerate(names)

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

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

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

  1. >>> list(enumerate(names))

  2. [(0, 'Bob'), (1, 'Alice'), (2, 'Guido')]

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

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

  2.    # ...

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

  • enumerate是Python的一个内置函数。你应该充分利用它通过循环迭代自动生成的索引变量。

  • 索引值默认从0开始,但也可以将其设置为任何整数。

  • enumerate函数是从2.3版本开始被添加到Python中的,详情见PEP279

  • Python的 enumerate函数可以帮助你编写出更加Pythonic和地道的循环结构,避免使用笨重且容易出错的手动生成索引。

  • 为了充分利用 enumerate的特性,一定要研究Python的迭代器和数据结构解包功能。


题图:pexels,CC0 授权。

点击阅读原文,查看更多 Python 教程和资源。



今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/TFB5psRudC
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/8185
 
388 次点击