enumerate的实现细节是什么?

7
Python有enumerate()函数可以用来遍历带有索引的对象。我怀疑解释器不会为了追踪位置而创建大量的整数对象。但是,PEP页面中说道:

它为所有可迭代对象提供了与iteritems()相同的优势,即紧凑、易读、可靠的索引表示。

那么这里有什么魔法呢?


Python在各个地方创建了许多int对象,但是将小值(范围在-5到256之间)进行了内部化。 - Martijn Pieters
@jamylak 我是 Python 的新手,所以我很难通过谷歌搜索找到源代码。这些文件中哪一个包含 enumerate 的源代码? - Forethinker
@Forethinker:http://hg.python.org/cpython/file/2.7/Objects/enumobject.c - Martijn Pieters
2个回答

17

enumerate()是一个迭代器;它只会在遍历时“即时”产生索引int值,而不是一次性地生成所有值。

您可以尝试阅读enumobject.c源代码,但它基本上可以像这样翻译成Python:

def enumerate(iterable, start=0):
    count = start
    for elem in iterable:
        yield count, elem
        count += 1
< p >使用 yield 关键字可以将其变为 生成器函数,您需要遍历该生成器(或在其上调用 next()),以便逐个 yield 调用推进函数产生数据。

Python 还会缓存 int 值,-5 到 256(含)之间的所有值都是单例,因此,直到达到 257,上述代码甚至不会生成新的 int 对象。


1
编程语言源代码对我来说仍然有点令人生畏。任何熟悉 yield 的人都会立刻明白这一点。非常感谢 Martijn! - Forethinker

2

它可以帮助你了解事物的位置...

l = ['apple', 'banana', 'cabbage']

for idx, item in enumerate(l):
    print "the item: %s, is at position %s" % (item, idx)

>>> 
the item: apple, is at position 0
the item: banana, is at position 1
the item: cabbage, is at position 2

在以下场景中,这很有帮助。想象一下,你想在列表中查找每个“卷心菜”项目,并知道它们的索引。

l = ['apple', 'banana', 'cabbage', 'monkey', 'kangaroo', 'cabbage']

def find_indexes(lst, match):
    results = []
    for idx, item in enumerate(l):
        if item == match:
            results.append(idx)
    return results

print find_indexes(l, 'cabbage')

>>> 
[2, 5]

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