2016-01-17 37 views

risposta

63

From the documentation:

di lista forniscono un modo conciso per creare liste. Le applicazioni comuni consistono nel creare nuovi elenchi in cui ogni elemento è il risultato di alcune operazioni applicate a ciascun membro di un'altra sequenza o iterabile o per creare una sottosequenza di quegli elementi che soddisfano una determinata condizione.


tua domanda, l'elenco di comprensione fa la stessa cosa come il seguente codice Python "semplice":

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

Come si scrive in una sola riga? Hmm ... possiamo ... probabilmente ... usiamo map() con lambda:

>>> list(map(lambda x: x**2, range(10))) 
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

ma non è più chiaro e più semplice di utilizzare solo una lista di comprensione?

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

In sostanza, siamo in grado di fare qualsiasi cosa con x. Non solo x**2. Ad esempio, eseguire un metodo di x:

>>> [x.strip() for x in ('foo\n', 'bar\n', 'baz\n')] 
['foo', 'bar', 'baz'] 

Oppure utilizzare x come argomento di un'altra funzione:

>>> [int(x) for x in ('1', '2', '3')] 
[1, 2, 3] 

Possiamo anche, ad esempio, utilizzare x come chiave di un oggetto dict. Vediamo:

>>> d = {'foo': '10', 'bar': '20', 'baz': '30'} 
>>> [d[x] for x in ['foo', 'baz']] 
['10', '30'] 

Che ne dici di una combinazione?

>>> d = {'foo': '10', 'bar': '20', 'baz': '30'} 
>>> [int(d[x].rstrip('0')) for x in ['foo', 'baz']] 
[1, 3] 

E così via.


È anche possibile utilizzare if o if...else in un elenco di comprensione. Ad esempio, si desidera solo numeri dispari in range(10). Si può fare:

>>> l = [] 
>>> for x in range(10): 
...  if x%2: 
...   l.append(x) 
>>> l 
[1, 3, 5, 7, 9] 

Ah è troppo complesso. Che mi dici della seguente versione?

>>> [x for x in range(10) if x%2] 
[1, 3, 5, 7, 9] 

Per utilizzare un if...else espressione ternaria, è necessario mettere il if ... else ... dopo x, non dopo range(10):

>>> [i if i%2 != 0 else None for i in range(10)] 
[None, 1, None, 3, None, 5, None, 7, None, 9] 

Avete sentito parlare di nested list comprehension? È possibile inserire due o più for s in un elenco comprensivo. Per esempio: parlare

>>> [i for x in [[1, 2, 3], [4, 5, 6]] for i in x] 
[1, 2, 3, 4, 5, 6] 

>>> [j for x in [[[1, 2], [3]], [[4, 5], [6]]] for i in x for j in i] 
[1, 2, 3, 4, 5, 6] 

Let circa la prima parte, che dà for x in [[1, 2, 3], [4, 5, 6]][1, 2, 3] e [4, 5, 6]. Quindi, for i in x fornisce 1, 2, 3 e 4, 5, 6.

Attenzione: Hai sempre bisogno di mettere for x in [[1, 2, 3], [4, 5, 6]]primafor i in x:

>>> [j for j in x for x in [[1, 2, 3], [4, 5, 6]]] 
Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
NameError: name 'x' is not defined 

Abbiamo anche set comprensioni, dict comprensioni, e generatore di espressioni.

set comprehensions e list comprehension sono fondamentalmente le stesse, ma il primo restituisce un impostati invece di un lista:

>>> {x for x in [1, 1, 2, 3, 3, 1]} 
{1, 2, 3} 

E 'lo stesso di:

>>> set([i for i in [1, 1, 2, 3, 3, 1]]) 
{1, 2, 3} 

A dict comprehensionassomiglia a una comprensione set, ma utilizza {key: value for key, value in ...} o {i: i for i in ...} anziché {i for i in ...}.

Ad esempio:

>>> {i: i**2 for i in range(5)} 
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16} 

Ed è uguale:

>>> d = {} 
>>> for i in range(5): 
...  d[i] = i**2 
>>> d 
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16} 

Vuol (i for i in range(5)) invia un tupla? No !, è un generator expression.Che restituisce un generatore:

>>> (i for i in range(5)) 
<generator object <genexpr> at 0x7f52703fbca8> 

E 'lo stesso di:

>>> def gen(): 
...  for i in range(5): 
...   yield i 
>>> gen() 
<generator object gen at 0x7f5270380db0> 

ed è possibile utilizzarlo come un generatore:

>>> gen = (i for i in range(5)) 
>>> next(gen) 
0 
>>> next(gen) 
1 
>>> list(gen) 
[2, 3, 4] 
>>> next(gen) 
Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
StopIteration 

Nota: Se si utilizza un list comprehension all'interno di una funzione, non è necessario il [] se tale funzione potesse scorrere su un generatore. Ad esempio, sum():

>>> sum(i**2 for i in range(5)) 
30 

correlati (circa generatori): Understanding Generators in Python.

+0

L'espressione ternaria 'x if cond else y' in realtà non ha nulla a che fare con le list comprehensions - qualsiasi espressione valida può essere utilizzata all'interno di una compressione di lista - l'espressione ternaria è una delle molte espressioni python. – AChampion

+3

@ AChampion: Sì, ne ho parlato nella mia risposta perché ho provato "[i for i in x if if else y]" mentre stavo imparando le list comprehensions e non funziona. Dopo alcune ricerche capisco che devo usare '[io se io altro y per i in x]' invece. Quindi penso che se lo menzionassi qui, altri potrebbero evitare il problema che avevo prima. –

+0

Vale la pena menzionare che è sufficiente usare il costruttore 'list':' list () 'in Python 3.x – styvane

7

Ci sono list, dictionary e set comprehension, ma nessuna comprensione di tuple (anche se si esplorano le "espressioni di generatore").

Affrontano il problema che i loop tradizionali in Python sono istruzioni (non restituiscono nulla) non espressioni che restituiscono un valore.

Non sono la soluzione a tutti i problemi e possono essere riscritti come loop tradizionali. Diventano scomodi quando lo stato deve essere mantenuto aggiornato & tra le iterazioni.

Essi in genere costituiti da:

[<output expr> <loop expr <input expr>> <optional predicate expr>] 

ma può essere ruotato in molti modi interessanti e bizzarre.

Possono essere analoghe alle tradizionali operazioni map() e filter() che ancora esistono in Python e continuano ad essere utilizzate.

Se fatti bene, hanno un quoziente di soddisfazione elevato.

+2

Questo ha reso la mia giornata: 'Quando fatto bene, hanno un quoziente di soddisfazione elevato. –

Problemi correlati