枚举列表已经是列表类型

enumerating list already of type list

我想知道是否有好心人可以解释为什么我必须在调用枚举之前转换一个已经是列表类型的列表。

>>> l = ['russell', 'bird', 'thomas']
>>> print(type(l))
Type is: `class 'list'`.

如果我在没有明确声明的情况下枚举这个列表,这就是输出:

>>> print(enumerate(l))
enumerate object at 0x00B1A0F8

将此列表显式声明为列表时,输出符合预期:

>>> print(list(enumerate(l)))
[(0, 'russell'), (1, 'bird'), (2, 'thomas')]

如果有人能帮助解释为什么会这样,我们将不胜感激。

您这里有两个不同的对象。假设您定义了一个函数:

def my_func(my_list):
    return 4

如果您my_func(l),当然不会return列表。嗯,enumerate()也是一样的道理。它 return 是一个 enumerate 对象,而不是列表。但是,该对象是可迭代的,因此可以将其转换为列表。例如:

def my_enumerate(my_list):
    index = 0
    for item in my_list:
        yield index, item
        index += 1

这几乎就是 enumerate 的工作原理。我们的函数是一个生成器函数,returns 是一个生成器对象。由于生成器是可迭代的,您可以将其转换为列表:

print(list(my_enumerate(l))

Python 文档在描述函数 returns 和 docs for enumerate() say that it returns an enumerate object, not a list. (Note that this was already the case in Python 2 时非常小心。)

虽然必须明确地创建一个完整的列表似乎有点痛苦,比如

print(list(enumerate(mylist)))

返回列表的优点是它可以更快并且使用更少的内存。预计在实际使用中,您通常不会一次需要整个列表,而是一次循环一个元素,例如

for i, elem in enumerate(mylist):
    print(i, '->', elem)

您甚至可能不会使用所有元素:

mylist = ['russell', 'bird', 'thomas']
for i, elem in enumerate(mylist):
    if elem == 'bird':
        break
    print((i, elem))

因此 enumerate() 让您可以高效地只在需要时生成项目,而不是一次生成所有项目。 (想象一下,如果您正在处理历史上所有 NBA 球员的名单,而不仅仅是您示例中的三名球员。)在极少数情况下,您确实确实一次需要所有项目,而不是 不得不输入 list(enumerate(mylist)) 很烦人。