enumerate () - Python'da bir jeneratör oluşturma


90

Bir jeneratör işlevinin sonucunu python'un enumerate () işlevine geçirdiğimde ne olacağını bilmek istiyorum. Misal:

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

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

Numaralandırma tembel bir şekilde mi yineleniyor yoksa her şeyi birinciye mi çeviriyor? Tembel olduğundan% 99,999 eminim, bu yüzden onu tamamen jeneratör işleviyle aynı şekilde değerlendirebilir miyim yoksa herhangi bir şeye dikkat etmem gerekir mi?


1
Sanırım çok Büyük Merhaba'da i arttırmak istiyorsunuz.
robert

@robert: Yanılmıyorsam otomatik olarak artar
the_drow

@the_drow veryBigHelloİşlevin kendisinde değil.
Will McCutchen

1
@Will: Oh, doğru. Ama bu sadece sinir bozucu. Bu bir örnek. Yine de düzeltildi.
the_drow

Yanıtlar:


108

Tembel. Durumun böyle olduğunu kanıtlamak oldukça kolaydır:

>>> 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

Bu Python 2 veya 3 (veya her ikisi) mi? İkisinde de tembel mi? Ben Python 2 üzerinde test ve bir tembel.
becko

2
Bunu Python 3.5.2'de test ettim ve tembel olarak değerlendiriyor.
gobernador

42

Söylemesi, önceki önerilerin herhangi birine göre daha kolaydır:

$ 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>

Numaralandırma tembel değerlendirme yapmadıysa, geri döner [(0,'a'), (1,'b'), (2,'c')]veya bir miktar (neredeyse) eşdeğerdir.

Tabii ki, numaralandırma gerçekten sadece süslü bir oluşturucu:

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

2
Bu açıklama için teşekkürler. Kabul edilen cevabı bulmakta biraz zorlandım. En azından seninkini görene kadar.
trendsetter37

13

Bu işlevi bellek istisnalarından çıkmadan çağırabildiğiniz için kesinlikle tembeldir.

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

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

0

Başka birinin (sklearn) yazdığı ve buradaki yaklaşımlarla işe yaramayan bir jeneratör kullandığım için eski okul alternatifi.

i=(-1)
for x in some_generator:
    i+=1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.