2012-10-16 1 views
17

Ho familiarità con il ciclo for in un contesto di codice di blocco. ad esempio:Python `for` syntax: codice di blocco vs espressioni generatore di linea singola

for c in "word": 
    print c 

Ho appena imbattuto in alcuni esempi che utilizzano for in modo diverso. Invece di iniziare con la dichiarazione for, la codificano alla fine di un'espressione (e non implicano un codice di blocco rientrato). ad esempio:

sum(x*x for x in range(10)) 

Qualcuno mi può puntare a qualche documentazione che illustra questo uso della for? Sono stato in grado di trovare esempi, ma non spiegazioni. Tutta la documentazione di for che sono stato in grado di trovare descrive l'uso precedente (esempio di codice di blocco). Non sono nemmeno sicuro di come chiamarlo, quindi mi scuso se il titolo della mia domanda non è chiaro.

risposta

15

Quello che stai indicando è Generator in Python. Date un'occhiata a: -

Vedere la documentazione: - Generator Expression che contiene esattamente lo stesso esempio che hai postato

Dalla documentazione: -

I generatori sono uno strumento semplice e potente per la creazione di iteratori. Loro sono scritti come normali funzioni ma usano la dichiarazione di rendimento ogni volta che vogliono restituire i dati. Ogni volta successiva() viene chiamato, il generatore riprende da dove si era-off (si ricorda valorizza tutti i dati e che dichiarazione è stata l'ultima eseguita)

generatori sono simili a List Comprehension che si utilizza con square brackets invece di brackets, ma sono più efficienti in termini di memoria. Non restituiscono allo stesso tempo lo list completo del risultato, ma restituiscono l'oggetto generatore. Ogni volta che si invoca next() sull'oggetto generator, il generatore utilizza yield per restituire il valore successivo.

List Comprehension per il codice di cui sopra sarebbe simile: -

[x * x for x in range(10)] 

è anche possibile aggiungere le condizioni per filtrare i risultati alla fine del per.

[x * x for x in range(10) if x % 2 != 0] 

Questo restituirà un elenco di numbers moltiplicato per 2 nell'intervallo da 1 a 5, se il numero non è divisibile per 2.

Un esempio di Generators raffigurante l'uso di yield può essere: -

def city_generator(): 
    yield("Konstanz") 
    yield("Zurich") 
    yield("Schaffhausen") 
    yield("Stuttgart") 

>>> x = city_generator() 
>>> x.next() 
Konstanz 
>>> x.next() 
Zurich 
>>> x.next() 
Schaffhausen 
>>> x.next() 
Stuttgart 
>>> x.next() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 

Quindi, si vede che, ogni chiamata a next() esegue il prossimo yield() in generator. e alla fine getta StopIteration.

+1

generatori e anche le list comprehensions, che sembrano molto simili: '[x * x per x nel range (10)]'. Puoi anche includere una condizione per filtrare i risultati: '[x * x per x nell'intervallo (10) se x% 2 == 0 o x% 3 == 0]'. –

4

sono quelli generator expressions e si sono legati alla list comprehensions

Lista comprensioni consentono la facile creazione di liste. Ad esempio, se si vuole creare un elenco di quadrati perfetti si potrebbe fare questo:

>>> squares = [] 
>>> for x in range(10): 
...  squares.append(x**2) 
... 
>>> squares 
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

Ma invece si potrebbe usare una lista di comprensione:

squares = [x**2 for x in range(10)] 

espressioni Generator sono come list comprehension, tranne che restituisce un oggetto generatore anziché una lista. È possibile eseguire iterazioni su questo oggetto generatore in modo simile per elencare le comprensibilità, ma non è necessario memorizzare l'intero elenco nella memoria in una sola volta, come si farebbe se si creasse l'elenco in una lista di comprensione.