enumerate()是什么意思?

349 投票
8 回答
409820 浏览
提问于 2025-04-17 20:45

在Python中,for row_number, row in enumerate(cursor): 这行代码的意思是:我们要遍历一个叫做`cursor`的东西,通常它是用来获取数据库查询结果的。

这里的`enumerate`是一个很有用的工具,它的作用是给我们遍历的每一行数据加上一个编号。简单来说,`row_number`就是当前行的编号,而`row`就是这一行的数据。这样,我们在处理数据的时候,就可以同时知道当前是第几行,方便我们进行后续的操作。

8 个回答

14

enumerate函数的工作原理如下:

doc = """I like movie. But I don't like the cast. The story is very nice"""
doc1 = doc.split('.')
for i in enumerate(doc1):
     print(i)

输出结果是

(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')
23

正如其他用户提到的,enumerate 是一个生成器,它会给可迭代的对象中的每个项目加上一个递增的索引。

比如说你有一个列表 l = ["test_1", "test_2", "test_3"],那么用 list(enumerate(l)) 你会得到类似这样的结果:[(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]

那这个有什么用呢? 一个可能的场景是,当你想遍历一些项目时,你可能只知道某个项目在列表中的位置(索引),但不知道它的具体值(因为在那时你还不知道它的值)。

for index, value in enumerate(joint_values):
   if index == 3:
       continue

   # Do something with the other `value`

这样你的代码会更清晰,因为你也可以用常规的 for 循环配合 range,但那样你在访问项目时就需要用索引(也就是 joint_values[i])。

虽然另一个用户提到过用 zip 实现 enumerate,但我觉得有一种更纯粹(但稍微复杂一点)的方式,不用 itertools,就是下面这个:

def enumerate(l, start=0):
    return zip(range(start, len(l) + start), l)

示例:

l = ["test_1", "test_2", "test_3"]
enumerate(l)
enumerate(l, 10)

输出:

[(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]

[(10, 'test_1'), (11, 'test_2'), (12, 'test_3')]

正如评论中提到的,这种用 range 的方法在处理任意可迭代对象时并不能像原来的 enumerate 函数那样有效。

25

我在读一本书,叫《Effective Python》,作者是Brett Slatkin。他展示了一种遍历列表的方法,同时还能知道当前项在列表中的索引位置,但他建议最好不要用这种方法,而是使用enumerate。虽然你问了enumerate是什么意思,但当我理解了下面的内容后,我也明白了enumerate是如何让遍历列表并知道当前项索引变得更简单(而且更易读)的。

list_of_letters = ['a', 'b', 'c']
for i in range(len(list_of_letters)):
    letter = list_of_letters[i]
    print (i, letter)

输出结果是:

0 a
1 b
2 c

在我了解enumerate函数之前,我以前也做过一些更傻的事情。

i = 0
for n in list_of_letters:
    print (i, n)
    i += 1

它产生的输出结果是一样的。

但是使用enumerate我只需要写:

list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
    print (i, letter)
98

这是一个内置函数,它会返回一个可以逐个访问的对象。你可以查看官方文档了解更多。

简单来说,它会遍历一个可迭代的对象(比如列表)中的元素,同时还会提供一个索引数字,这些内容会组合成一个元组:

for item in enumerate(["a", "b", "c"]):
    print item

打印输出

(0, "a")
(1, "b")
(2, "c")

这个函数很有用,特别是当你想要遍历一个序列(或其他可迭代的东西),同时又想要一个索引计数器的时候。如果你希望计数器从其他值开始(通常是1),你可以把这个值作为第二个参数传给enumerate

537

enumerate() 函数的作用是给一个可迭代的对象(比如列表)添加一个计数器。

也就是说,对于 cursor 中的每个元素,它会生成一个包含 (计数器, 元素) 的元组;在 for 循环中,这个元组会分别绑定到 row_numberrow 这两个变量上。

示例:

>>> elements = ('foo', 'bar', 'baz')
>>> for elem in elements:
...     print elem
... 
foo
bar
baz
>>> for count, elem in enumerate(elements):
...     print count, elem
... 
0 foo
1 bar
2 baz

默认情况下,enumerate()0 开始计数,但如果你给它第二个整数参数,它就会从那个数字开始计数:

>>> for count, elem in enumerate(elements, 42):
...     print count, elem
... 
42 foo
43 bar
44 baz

如果你想在 Python 中重新实现 enumerate(),有两种方法可以做到;一种是使用 itertools.count() 来进行计数,另一种是在一个 生成器函数 中手动计数:

from itertools import count

def enumerate(it, start=0):
    # return an iterator that adds a counter to each element of it
    return zip(count(start), it)

还有

def enumerate(it, start=0):
    count = start
    for elem in it:
        yield (count, elem)
        count += 1

在 C 语言中的 实际实现 更接近后者,它进行了优化,以便在常见的 for i, ... 解包情况下重用一个元组对象,并使用标准的 C 整数值作为计数器,直到计数器变得太大,以至于需要使用 Python 的整数对象(这个对象没有上限)。

撰写回答