Answers:
该enumerate()
函数向可迭代对象添加一个计数器。
因此,对于其中的每个元素cursor
,将生成一个元组(counter, element)
;的for
环结合,要row_number
和row
分别。
演示:
>>> 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
如果要enumerate()
在Python中重新实现,可以通过以下两种方法来实现。一个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整数对象(无界)。
它是一个内置函数,可返回可以迭代的对象。请参阅文档。
简而言之,它遍历组合在一个元组中的可迭代元素(如列表)以及索引号:
for item in enumerate(["a", "b", "c"]):
print item
版画
(0, "a")
(1, "b")
(2, "c")
如果要遍历一个序列(或其他可迭代的事物),并且还希望有一个可用的索引计数器,这将很有帮助。如果您希望计数器从其他值(通常为1)开始,则可以将其作为第二个参数enumerate
。
item
则可以删除括号:D
yield
/ yield from
或生成器表达式(隐式地yield
));enumerate
不是发电机。对于所有与鸭子输入相关的目的没有什么区别,但是显式类型检查和Python语言文档仅将术语“生成器”用于一种目的,但没有涵盖enumerate
。
我正在阅读Brett Slatkin 的书(《Effective Python》),他展示了另一种遍历列表的方法,并且知道列表中当前项目的索引,但是他建议最好不要使用它,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)
正如其他用户所提到的那样,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]
)。
尽管另一个用户提到了enumerate
using 的实现zip
,但我认为没有使用一种更纯净(但稍微复杂一点)的方法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
函数一样。
itertools
是您的range
方法仅适用于容器。enumerate
与任意可迭代项一起工作;如果您要迭代文件,for lineno, line in enumerate(myfile):
可以使用,但是您不能这样做,range(len(myfile))
因为直到达到EOF为止,长度是未知的。
枚举函数的工作方式如下:
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')