python 中的枚举是懒惰的吗?

发布于 2024-09-12 19:18:23 字数 386 浏览 7 评论 0原文

我想知道当我将生成器函数的结果传递给 python 的 enumerate() 时会发生什么。示例:

def veryBigHello():
    i = 0
    while i < 10000000:
        i += 1
        yield "hello"

numbered = enumerate(veryBigHello())
for i, word in numbered:
    print i, word
    

枚举是惰性迭代的,还是首先将所有内容放入 中?我 99.999% 确定它是惰性的,所以我可以将它与生成器函数完全相同,还是我需要注意什么?

I'd like to know what happens when I pass the result of a generator function to python's enumerate(). Example:

def veryBigHello():
    i = 0
    while i < 10000000:
        i += 1
        yield "hello"

numbered = enumerate(veryBigHello())
for i, word in numbered:
    print i, word
    

Is the enumeration iterated lazily, or does it slurp everything into the <enumerate object> first? I'm 99.999% sure it's lazy, so can I treat it exactly the same as the generator function, or do I need to watch out for anything?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

始终不够 2024-09-19 19:18:23

它很懒。证明情况确实如此是相当容易的:

>>> def abc():
...     letters = ['a','b','c']
...     for letter in letters:
...         print letter
...         yield letter
...
>>> numbered = enumerate(abc())
>>> for i, word in numbered:
...     print i, word
...
a
0 a
b
1 b
c
2 c

It's lazy. It's fairly easy to prove that's the case:

>>> def abc():
...     letters = ['a','b','c']
...     for letter in letters:
...         print letter
...         yield letter
...
>>> numbered = enumerate(abc())
>>> for i, word in numbered:
...     print i, word
...
a
0 a
b
1 b
c
2 c
把回忆走一遍 2024-09-19 19:18:23

它比之前的建议更容易判断:

$ python
Python 2.5.5 (r255:77872, Mar 15 2010, 00:43:13)
[GCC 4.3.4 20090804 (release) 1] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> abc = (letter for letter in 'abc')
>>> abc
<generator object at 0x7ff29d8c>
>>> numbered = enumerate(abc)
>>> numbered
<enumerate object at 0x7ff29e2c>

如果 enumerate 没有执行惰性求值,它将返回 [(0,'a'), (1,'b'), (2,'c') ] 或一些(几乎)等效的东西。

当然,枚举实际上只是一个奇特的生成器:

def myenumerate(iterable):
   count = 0
   for _ in iterable:
      yield (count, _)
      count += 1

for i, val in myenumerate((letter for letter in 'abc')):
    print i, val

It's even easier to tell than either of the previous suggest:

$ python
Python 2.5.5 (r255:77872, Mar 15 2010, 00:43:13)
[GCC 4.3.4 20090804 (release) 1] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> abc = (letter for letter in 'abc')
>>> abc
<generator object at 0x7ff29d8c>
>>> numbered = enumerate(abc)
>>> numbered
<enumerate object at 0x7ff29e2c>

If enumerate didn't perform lazy evaluation it would return [(0,'a'), (1,'b'), (2,'c')] or some (nearly) equivalent.

Of course, enumerate is really just a fancy generator:

def myenumerate(iterable):
   count = 0
   for _ in iterable:
      yield (count, _)
      count += 1

for i, val in myenumerate((letter for letter in 'abc')):
    print i, val
不一样的天空 2024-09-19 19:18:23

由于您可以调用此函数而不会出现内存不足异常,因此它绝对是懒惰的

def veryBigHello():
    i = 0
    while i < 1000000000000000000000000000:
        yield "hello"

numbered = enumerate(veryBigHello())
for i, word in numbered:
    print i, word

Since you can call this function without getting out of memory exceptions it definitly is lazy

def veryBigHello():
    i = 0
    while i < 1000000000000000000000000000:
        yield "hello"

numbered = enumerate(veryBigHello())
for i, word in numbered:
    print i, word
半衬遮猫 2024-09-19 19:18:23

老派的替代方案,因为我使用的是其他人(sklearn)编写的生成器,该生成器不适用于此处的方法。

i=(-1)
for x in some_generator:
    i+=1

Old school alternative since I was using a generator that someone else (sklearn) wrote that didn't work with the approaches here.

i=(-1)
for x in some_generator:
    i+=1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文