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

Alcune operazioni da from itertools import *:

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]

Link