La comprehension delle liste offrono un modo più conciso per scrivere un loop for. Possono tornare veramente utili quando vuoi creare nuove liste da liste o iterables già esistenti.

Ad esempio, potremmo utilizzare la list comprehension per creare una nuova lista di numeri elevati al quadrato, da una preesistente lista di numeri (map).
Un altro esempio potrebbe essere di creare una nuova lista includendo solamente alcuni elementi di una vecchia lista (filter).

Vediamo quindi come si usa questo costrutto tanto amato dai pythonisti:

[ for  in ]

Un esempio su come usarlo per moltiplicare ogni elementi di una lista di numeri per 5 è questo:

numbers = []
for i in range(10): # Popoliamo la lista numbers
 numbers.append(i)
fiveNumbers = [i * 5 for i in numbers] # Moltiplichiamo ogni numero per 5

Dopo l’esecuzione di queste istruzioni, ci ritroveremo con due liste:

>>> numbers
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> fiveNumbers
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45]

La lista numbers è rimasta intatta. La lista fiveNumbers invece, è stata popolata con gli elementi di numbers moltiplicati per 5.

Quello che avremmo potuto fare in alternativa, sarebbe stato un più verboso:

fiveNumbers = []
for i in numbers:
 fiveNumbers.append(i*5)

In questo modo avremmo raggiunto lo stesso risultato. Vedendo il for così, e’ più facile capire il funzionamento della list comprehension:

newList = []
for  in :
 newList.append()

Un altro modo, sarebbe stato quello di utilizzare il costrutto map(). Questo ci permette di eseguire una funzione su tutti gli elementi di una lista:

fiveNumbers = map(lambda x : x*5, numbers)

Nonostante sia abbastanza facile capirlo (sopratutto se conosci già il costrutto lambda per creare funzioni anonime), se non lo conosci non è importante. Ti basterà sapere che le list comprehension sono il modo più “pythonista” per svolgere questo compito.

List Comprehensions con condizioni

Iterando sulla lista, è anche possibile applicare l’espressione solo al verificarsi di una condizione. Ad esempio, potremmo creare una nuova lista formata solo dagli elementi che soddisfino una certa proprietà. Questo è possibile usando il costrutto if.... Vediamo come:

[ for  in  if ]

Ad esempio, vediamo come si fa ad ottenere una lista di numeri pari dalla precedente lista fiveNumbers. Iniziamo col metodo più verboso questa volta:

evenFiveNumbers = []
for i in fiveNumbers:
 if i % 2 == 0: # Controllo se è un numero pari
  evenFiveNumbers.append(i)

L’operatore percentuale permette di avere il resto della divisione di un numero, in questo caso viene usato per controllare se i è un numero pari. Vediamo invece come si può fare in maniera più rapida con la list comprehension:

>>> fiveNumbers
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45]
>>> evenFiveNumbers = [i * 5 for i in numbers if i % 2 == 0] 
>>> evenFiveNumbers
[0, 10, 20, 30, 40]

Anche in questo caso, avremmo potuto usare il costrutto funzionale filter per eseguire il filtraggio dei numeri dispari, e una map per la moltiplicazione:

map(lambda i: (i * 5), filter(lambda i: i%2==0, numbers))

Come possiamo vedere, usare map/filter può portare allo stesso risultato ma in maniera meno chiara. Leggendo la versione in list comprehension è molto più facile capire quello che sta facendo il programma.

E’ possibile anche aggiungere una condizione if...else... all’interno della list comprehension, ma in quel caso l’ordine cambia. La definizione del costrutto infatti è la seguente:

[ if  else  for  in ]

La lettura in italiano potrebbe essere “Fai questo se condizione è vera, altrimenti quest’altro e fallo per ogni elemento della lista”. Come esempio, renderemo ogni numero di numbers un numero pari. Vediamo prima come farlo nella modalità verbosa:

evenFiveNumbers = []
for i in numbers:
 if i % 2 == 0:
  evenFiveNumebers.append(i)
 else:
  evenFiveNumebers.append(i + 1)

Per quanto riguarda la versione con la list comprehension invece abbiamo:

>>> [i if i % 2 == 0 else i+1 for i in numbers]
[0, 2, 2, 4, 4, 6, 6, 8, 8, 10]

Conclusione

Le list comprehension sono siuramente un costrutto elegante ed utile, che ci servirà molto spesso durante la vostra carriera di sviluppatori.

Documentazione ufficiale su python3: https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions