2010-08-03 16 views
49

Mi piacerebbe sapere cosa succede quando passo il risultato di una funzione generatore a enumerate python(). Esempio:enumerate() - un generatore in Python

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

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

L'enumerazione è iterata in modo laziale o si beve tutto nel primo? Sono sicuro al 99,999% che sia pigro, quindi posso trattarlo esattamente come la funzione generatore o devo fare attenzione a qualcosa?

+0

presumo si intende incrementare i in veryBigHello. – robert

+0

@robert: se non mi sbaglio, viene automaticamente aumentato –

+0

@the_drow Non nella funzione 'veryBigHello'. –

risposta

61

È pigro. E 'abbastanza facile dimostrare che è il caso:

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

È questo Python 2 o 3 (o entrambi)? È pigro in entrambi? Ho provato su Python 2 e * è * pigro. – becko

10

Dal momento che si può chiamare questa funzione senza uscire di eccezioni di memoria è sicuramente è pigro

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

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

E' ancora più facile da dire che uno dei due precedenti suggeriscono :

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

Se enumerate non ha effettuato la valutazione pigra che sarebbe tornato [(0,'a'), (1,'b'), (2,'c')] o qualche (quasi) equivalente.

Naturalmente, enumerare è in realtà solo un generatore di fantasia:

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

Grazie per questa spiegazione. Ho avuto un po 'di difficoltà a capire la risposta accettata. Almeno fino a quando non ho visto il tuo. – trendsetter37

+1

Questa dovrebbe essere la risposta accettata – cowbert

Problemi correlati