Python versione Bignami - Generatori
Concetti di base
Un iteratore è un oggetto che ha un metodo next()
che restituisce un valore o
lancia l'eccezione StopIteration
.
Un generatore è una funzione che restituisce un iteratore.
Una funzione che contiene il comando yield
viene automaticamente convertita
in una funzione che restituisce un iteratore.
Creazione
Da funzione:
def potenze(base): val = base while True: yield val val = val * base def linee_numerate(file): indice = 0 for linea in file: yield indice, linea indice = indice + i # Stampa le potenze di 2 for i in potenze(2): print i # Mostra che il generatore 'potenze' restituisce un iteratore iter = potenze(2) while True: try: print iter.next() except StopIteration: break
In una classe:
class TreeNode: def __iter__(self): for node in self.children: yield node
Definiti al volo:
a = (line[:-1] for line in file) for line in a: print line a = (x.real, x.imag for x in complexNumbers) for r, i in a: print "Reale: %.2f, immag.: %.2f" % (r, i)
Da un altro oggetto:
lista = [1,2,3,4,5] a = iter(lista)
Operazioni
for i in iter:
itera gli elementi generatienumerate(iter)
restituisce un generatore che genera coppie (indice, elemento di iter)
Alcune operazioni da from itertools import *
:
chain(iter1, iter2...)
restituisce un generatore che genera tutti i risultati di iter1, poi quelli di iter2, poi iter3 e cosí via.cycle(iter1)
genera i risultati di iter1, salvandoli. Quando iter1 finisce, ne rigenera i risultati all'infinito.ifilter(funzione, iter)
genera soli i risultatii
di iter per i qualifunzione(i)
restituisce trueimap(funzione, iter)
passa uno a uno afunzione
i risultati diiter
e genera i risultatiislice(iter, [start,] stop [,step])
restituisce gli elementi di iter a partire da quello in posizionestart
(o dal primo), fino a quello in posizionestop
(escluso), eventualmente prendendone uno ognistep
.izip(iter1, iter2, ...)
genera una tupla coi primi elementi di ogni iteratore, poi una tupla coi secondi, poi coi terzi e cosí viarepeat(val [, times])
crea un generatore che genera sempreval
.times
indica dopo quanto fermarsi, e se non è specificato non si ferma mai.x, y, z = tee(iter, 3)
genera vari cloni diiter
Esempi:
# Aggiunge alla lista a tutte le righe del file, convertite in numeri interi a.extend(imap(int,file)) # Stampa le righe di un file, una ogni tre for i, riga in enumerate(file): if i % 3 == 0: print riga[:-1] # Stampa le righe di file1 concatenate a quelle di file2 for riga1, riga2 in izip(file1, file2): print riga1[:-1], riga2[:-1]