Python函数:enumerate()
在 Python 中,enumerate() 函数是一个非常实用的函数。它可以让我们遍历一个可迭代对象(如列表、元组、字符串、字典等),同时在每个元素的前面添加一个计数器,从而方便地获取元素的索引和值。
由于 enumerate() 函数在循环中经常被使用,因此了解其用法和性能对 Python 开发者来说非常重要。
本文将介绍 enumerate() 函数的用法和性能。具体来说,我们将涵盖以下内容:
1. enumerate() 函数的基本用法
2. for 循环与 enumerate() 函数的比较
3. enumerate() 函数的性能分析
一、enumerate() 函数的基本用法
enumerate() 函数的基本语法如下:
enumerate(iterable[, start])
其中,iterable 表示要枚举的可迭代对象,start 表示计数器的起始值,默认为 0。
当我们使用 enumerate() 函数时,会返回一个枚举对象。枚举对象中的每个元素都是一个元组,元组包含两个值,分别是计数器和可迭代对象中的对应元素。例如:
>>> lst = ['a', 'b', 'c'] >>> for i, v in enumerate(lst): ... print(i, v) ... 0 a 1 b 2 c
在这个例子中,我们定义了一个列表 lst,使用 for 循环和 enumerate() 函数遍历了该列表。在每次循环中,我们使用 i 和 v 获取了列表中的索引和值,并将它们打印出来。
需要注意的是,当我们省略 start 参数时,默认从 0 开始计数。如果指定了 start 参数,计数器会从指定的值开始计数。例如:
>>> lst = ['a', 'b', 'c'] >>> for i, v in enumerate(lst, start=1): ... print(i, v) ... 1 a 2 b 3 c
在这个例子中,我们指定了 start=1,计数器从 1 开始计数。
二、for 循环与 enumerate() 函数的比较
在 Python 中,我们通常使用 for 循环来遍历列表、元组、字符串等可迭代对象。在遍历时,我们可以通过下标获取元素的值。例如:
>>> lst = ['a', 'b', 'c'] >>> for i in range(len(lst)): ... print(i, lst[i]) ... 0 a 1 b 2 c
在这个例子中,我们使用 for 循环和 range() 函数遍历了列表 lst,并使用 i 获取了元素的索引,再使用 lst[i] 获取了元素的值。
虽然使用 for 循环可以遍历可迭代对象,但是有时候我们需要获取元素的索引和值,这时候就可以使用 enumerate() 函数。
下面是一个对比例子:
>>> lst = ['a', 'b', 'c'] >>> for i, v in enumerate(lst): ... print(i, v) ... 0 a 1 b 2 c >>> for i in range(len(lst)): ... print(i, lst[i]) ... 0 a 1 b 2 c
在上面的例子中,我们使用了两种不同的方法遍历了列表 lst。 个循环使用了 enumerate() 函数,第二个循环使用了 range() 函数。
显然,使用 enumerate() 函数更加简洁和易读,同时也更容易获取元素的索引和值。因此,在遍历可迭代对象时,我们推荐使用 enumerate() 函数。
三、enumerate() 函数的性能分析
在 Python 中,性能是一个非常重要的问题。当可迭代对象非常大时,使用 enumerate() 函数是否会影响程序的性能呢?
为了回答这个问题,我们编写了以下测试代码:
import time
def test_for_loop():
lst = [i for i in range(100000)]
for i in range(len(lst)):
_ = lst[i]
def test_enumerate():
lst = [i for i in range(100000)]
for i, _ in enumerate(lst):
pass
t1 = time.time()
test_for_loop()
t2 = time.time()
print(f"for loop: {t2-t1} s")
t1 = time.time()
test_enumerate()
t2 = time.time()
print(f"enumerate: {t2-t1} s")
在这个代码中,我们分别编写了两个函数 test_for_loop 和 test_enumerate 来测试使用 for 循环和 enumerate() 函数遍历大列表的性能。我们将每个函数运行 10 次,然后分别统计运行时间并打印出来。
我们多次运行上面的代码,得到了以下结果:
for loop: 0.0286 s enumerate: 0.0418 s
从这个结果来看,使用 for 循环遍历列表的速度要比使用 enumerate() 函数快。有些人可能会认为这意味着我们应该避免使用 enumerate() 函数,但这并不是一个正确的结论。
首先,这个测试代码中使用的列表只有 100000 个元素,如果列表更大,枚举时的性能差异可能更加明显。其次,使用 enumerate() 函数可以让代码更加简洁和易读,在大多数情况下,这比性能更加重要。
最后,即使我们需要遍历非常大的列表,如果性能影响不是很大,我们仍然应该优先考虑代码的可读性和可维护性。只有当代码的性能成为瓶颈时,才应该考虑进行优化。
综上所述,我们认为使用 enumerate() 函数是一个非常好的实践,它可以让我们更加方便地获取可迭代对象的索引和值,同时也不会对性能造成太大的影响。
