枚举(enumerate())函数是什么意思?

347

for row_number, row in enumerate(cursor):在Python中是什么意思?

在这个上下文中,enumerate是什么意思?


23
好的,下面是您需要翻译的内容:http://docs.python.org/2/library/functions.html#enumerate - ndpu
https://docs.python.org/3/library/functions.html#enumerate - Mechanic Pig
8个回答

535

enumerate()函数向可迭代对象添加计数器。

因此,对于cursor中的每个元素,都会生成一个包含(counter, element)的元组;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 开始计数,但如果您提供第二个整数参数,它将从该数字开始:

默认情况下,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整数对象(它是无界的)。


97

这是一个内置函数,它返回一个可以迭代的对象。请参见文档

简而言之,它循环遍历一个可迭代对象(如列表)的元素,并将其索引号与元素组合成一个元组:

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

打印

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

如果您想遍历序列(或其他可迭代的东西)并且还想拥有索引计数器,则使用enumerate非常有用。如果您希望计数器从其他值(通常为1)开始,可以将其作为第二个参数传递给enumerate


1
如果你给item增加第二个变量,那么你就可以去掉括号 :D - Abdelouahab
2
过于追求细节:这是一个返回迭代器而不是生成器的函数。生成器是一种特定类别的用户定义函数(使用yield/yield from或生成器表达式,它们隐式地yield);enumerate不是生成器。对于所有与鸭子类型相关的目的,没有区别,但显式类型检查和Python语言文档仅将术语“生成器”用于一个目的,这并不包括enumerate - ShadowRanger

25

我正在阅读Brett Slatkin的一本书(Effective Python),他展示了另一种遍历列表并知道当前项在列表中的索引的方法,他建议最好不要使用它,而是使用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)

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`

所以你的代码读起来更好,因为你也可以用range进行常规的循环,但是要访问项目,你需要索引它们(即joint_values[i])。

虽然另一个用户提到了使用zipenumerate实现,但我认为一种更纯粹(但稍微复杂一些)且不使用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')]

正如评论中所提到的,这种使用范围的方法不能像原始的enumerate函数一样适用于任意可迭代对象。


1
另一个回答提到itertools的原因是,您的range方法仅适用于容器。 enumerate可用于任意可迭代对象;如果要遍历文件,则for lineno, line in enumerate(myfile):可行,但您不能执行range(len(myfile)),因为在达到EOF之前无法确定长度。 - ShadowRanger

14
枚举函数的工作原理如下:
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')

0

enumerate函数可以同时计算元素的索引和值。我相信以下代码将有助于解释正在发生的事情。

for i,item in enumerate(initial_config):
     print(f'index{i} value{item}')

0

我假设您知道如何在某个列表中迭代元素:

for el in my_list:
    # do something

有时候在编程中,你不仅需要迭代元素,还需要每次迭代的索引。一种方法是:
i = 0
for el in my_list:
    # do somethings, and use value of "i" somehow
    i += 1

然而,更好的方法是使用函数“enumerate”。枚举的作用是接收一个列表,并返回一个类似于列表的对象(可迭代的对象),但这个新列表的每个元素本身都包含两个元素:原始输入列表中的索引和值: 所以如果你有

arr = ['a', 'b', 'c']

然后命令enumerate(arr)返回类似于:

[(0,'a'), (1,'b'), (2,'c')]

现在,如果您迭代一个列表(或可迭代对象),其中每个元素本身具有2个子元素,则可以像下面这样在for循环中捕获这两个子元素:

for index, value in enumerate(arr):
    print(index,value)

这将打印出enumerate输出的子元素。

通常,您可以将列表中的多个项“解包”到多个变量中,如下所示:

idx,value = (2,'c')
print(idx)
print(value)

这将会打印

2
c

这是在每次循环中使用 enumerate(arr) 作为可迭代对象发生的任务类型。


0
enumerate函数用于计算迭代的次数。它接受两个参数:一个可迭代对象和一个起始索引,如下所示:enumerate(iterable, start=1) 如果没有指定起始索引,默认从0开始。它返回迭代的索引和对应的元素。考虑以下示例:
for i, j in enumerate(range(5)):
    print(i,'=',j)

输出将是:
0 = 0
1 = 1
2 = 2
3 = 3
4 = 4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接