Skip to content

Comprensione delle liste in Python

Python

In Python, puoi creare un nuovo elenco usando la comprensione degli elenchi. È più semplice che usare il ciclo per.

In questo articolo vengono descritti i seguenti contenuti.

  • Nozioni di base sulla comprensione delle liste
  • Elenca le comprensioni con se
  • Elenca le comprensioni con espressioni condizionali (come se altro)
  • Elenca le comprensioni con zip(), enumerate()
  • Comprensioni di elenchi nidificati
  • Stabilisci le comprensioni
  • Comprensioni del dizionario
  • Espressione del generatore

Vedere il seguente articolo per le basi dell’istruzione per.

Vedere l’articolo seguente per esempi di utilizzo della comprensione degli elenchi.

Nozioni di base sulla comprensione delle liste

Le comprensioni degli elenchi sono scritte come segue:

[expression for variable_name in iterable]

Ogni elemento di iterable, come una lista o una tupla, viene estratto come nome_variabile e valutato con expression. Viene creato un nuovo elenco con il risultato valutato da expression come elemento.

Viene mostrato un esempio di comprensione di elenchi con un’istruzione equivalente.

squares = [i**2 for i in range(5)]
print(squares)
# [0, 1, 4, 9, 16]
squares = []
for i in range(5):
    squares.append(i**2)

print(squares)
# [0, 1, 4, 9, 16]

oltre map() possa fare la stessa cosa, la comprensione dell’elenco è preferita per semplicità e chiarezza.

Elenca le comprensioni con se

Nelle comprensioni degli elenchi, se può essere utilizzato come segue:

[expression for variable_name in iterable if condition]

Solo gli elementi di iterable che sono True for condition vengono valutati con expression. Gli elementi di iterable che sono False per condizione non sono inclusi nell’elenco dei risultati.

odds = [i for i in range(10) if i % 2 == 1]
print(odds)
# [1, 3, 5, 7, 9]
odds = []
for i in range(10):
    if i % 2 == 1:
        odds.append(i)

print(odds)
# [1, 3, 5, 7, 9]

oltre filter() possa fare la stessa cosa, la comprensione dell’elenco è preferita per semplicità e chiarezza.

Elenca le comprensioni con espressioni condizionali (come se altro)

Nell’esempio precedente, gli elementi che non soddisfano la condizione sono esclusi dal nuovo elenco.

Se vuoi applicare un’altra operazione agli elementi che non soddisfano la condizione, come in caso contrario, usa le espressioni condizionali.

In Python, le espressioni condizionali possono essere scritte come segue:

X è il valore o l’espressione per True e Y è il valore o l’espressione per False.

Puoi usare la parte dell’espressione delle comprensioni degli elenchi:

odd_even = ['odd' if i % 2 == 1 else 'even' for i in range(10)]
print(odd_even)
# ['even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']
odd_even = []
for i in range(10):
    if i % 2 == 1:
        odd_even.append('odd')
    else:
        odd_even.append('even')

print(odd_even)
# ['even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']

È inoltre possibile applicare diverse operazioni all’elemento originale a seconda della condizione come segue:

odd10 = [i * 10 if i % 2 == 1 else i for i in range(10)]
print(odd10)
# [0, 10, 2, 30, 4, 50, 6, 70, 8, 90]

Elenca le comprensioni con zip(), enumerate()

Nell’istruzione per vengono spesso utilizzati zip() ed enumerate(). zip() aggrega elementi da più iterabili ed enumerate() riporta un valore e il suo indice.

Naturalmente, puoi anche usare zip() ed enumerate() nelle comprensioni degli elenchi.

Elenca le comprensioni con zip():

l_str1 = ['a', 'b', 'c']
l_str2 = ['x', 'y', 'z']

l_zip = [(s1, s2) for s1, s2 in zip(l_str1, l_str2)]
print(l_zip)
# [('a', 'x'), ('b', 'y'), ('c', 'z')]
l_zip = []
for s1, s2 in zip(l_str1, l_str2):
    l_zip.append((s1, s2))

print(l_zip)
# [('a', 'x'), ('b', 'y'), ('c', 'z')]

Elenca le comprensioni con enumerate():

l_enu = [(i, s) for i, s in enumerate(l_str1)]
print(l_enu)
# [(0, 'a'), (1, 'b'), (2, 'c')]
l_enu = []
for i, s in enumerate(l_str1):
    l_enu.append((i, s))

print(l_enu)
# [(0, 'a'), (1, 'b'), (2, 'c')]

Puoi anche usare se.

l_zip_if = [(s1, s2) for s1, s2 in zip(l_str1, l_str2) if s1 != 'b']
print(l_zip_if)
# [('a', 'x'), ('c', 'z')]

È anche possibile calcolare un nuovo valore utilizzando ogni elemento.

l_int1 = [1, 2, 3]
l_int2 = [10, 20, 30]

l_sub = [i2 - i1 for i1, i2 in zip(l_int1, l_int2)]
print(l_sub)
# [9, 18, 27]

Comprensioni di elenchi nidificati

Le comprensioni degli elenchi possono essere nidificate proprio come sono nidificati i cicli for.

[expression for variable_name1 in iterable1
    for variable_name2 in iterable2
        for variable_name3 in iterable3 ... ]

Le interruzioni di riga e il rientro vengono aggiunti per comodità, ma non sono obbligatori.

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

flat = [x for row in matrix for x in row]
print(flat)
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
flat = []
for row in matrix:
    for x in row:
        flat.append(x)

print(flat)
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

Un altro esempio:

cells = [(row, col) for row in range(3) for col in range(2)]
print(cells)
# [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]

Puoi anche usare se.

cells = [(row, col) for row in range(3)
         for col in range(2) if col == row]
print(cells)
# [(0, 0), (1, 1)]
cells = [(row, col) for row in range(3) if row % 2 == 0
         for col in range(2) if col % 2 == 0]
print(cells)
# [(0, 0), (2, 0)]

Stabilisci le comprensioni

Se si modificano le parentesi quadre [] nella comprensione dell’elenco con le parentesi graffe {}, viene creato un insieme (oggetto di tipo set).

{expression for variable_name in iterable}
s = {i**2 for i in range(5)}

print(s)
# {0, 1, 4, 9, 16}

Per ulteriori informazioni sul set, vedere l’articolo seguente.

Comprensioni del dizionario

I dizionari (oggetti di tipo dict) possono essere creati anche con la comprensione del dizionario.

Usa {} e specifica la chiave e il valore nella parte dell’espressione come chiave: valore.

{key: value for variable_name in iterable}

Qualsiasi valore o espressione può essere specificato per chiave e valore.

l = ['Alice', 'Bob', 'Charlie']

d = {s: len(s) for s in l}
print(d)
# {'Alice': 5, 'Bob': 3, 'Charlie': 7}

Usa la funzione zip() per creare un nuovo dizionario da ciascun elenco di chiavi e valori.

keys = ['k1', 'k2', 'k3']
values = [1, 2, 3]

d = {k: v for k, v in zip(keys, values)}
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3}

Per altri modi per creare manuali, vedere gli articoli seguenti

Espressioni del generatore

Se la parentesi quadra [] nella comprensione dell’elenco viene modificato in parentesi (), viene restituito il generatore al posto della tupla. Questa chiamata è espressione del generatore.

Comprensione dell’elenco:

l = [i**2 for i in range(5)]

print(l)
# [0, 1, 4, 9, 16]

print(type(l))
# <class 'list'>

Espressione del generatore:

print() non porta gli elementi del generatore. Puoi ottenere elementi usando l’istruzione per.

g = (i**2 for i in range(5))

print(g)
#  at 0x10af944f8>

print(type(g))
# <class 'generator'>

for i in g:
    print(i)
# 0
# 1
# 4
# 9
# 16

È possibile utilizzare if e nidificare con le espressioni del generatore e le comprensioni degli elenchi.

g_cells = ((row, col) for row in range(0, 3)
           for col in range(0, 2) if col == row)

print(type(g_cells))
# <class 'generator'>

for i in g_cells:
    print(i)
# (0, 0)
# (1, 1)

Ad esempio, se un elenco con molti elementi viene creato con le comprensioni degli elenchi e utilizzato nel ciclo for, le comprensioni degli elenchi creano inizialmente un elenco contenente tutti gli elementi.

D’altra parte, le espressioni del generatore creano gli elementi uno per uno dopo ogni ciclo, in modo che l’utilizzo della memoria possa essere ridotto.

È possibile omettere le parentesi () se l’espressione del generatore è l’unico argomento passato alla funzione.

print(sum([i**2 for i in range(5)]))
# 30

print(sum((i**2 for i in range(5))))
# 30

print(sum(i**2 for i in range(5)))
# 30

Non ci sono comprensioni delle tuple, ma è possibile creare tuple passando l’espressione del generatore a tuple().

t = tuple(i**2 for i in range(5))

print(t)
# (0, 1, 4, 9, 16)

print(type(t))
# <class 'tuple'>