Python map() Funzione, spiegata con esempi

In questo tutorial, esplorerai l’utilizzo della funzione `map()` di Python per applicare una specifica operazione a ogni elemento di una struttura dati iterabile.

Python supporta un approccio alla programmazione noto come paradigma funzionale, che permette di strutturare il codice come una serie di calcoli eseguiti da funzioni. In questo contesto, le funzioni Python sono trattate come oggetti di prima classe: ciò significa che una funzione può essere passata come parametro a un’altra funzione, oppure essere restituita come risultato di un’altra funzione.

La funzione `map()` è un’utility che riceve una funzione come argomento e ti dà la possibilità di applicarla a ogni elemento contenuto in una sequenza.

Al termine di questo percorso didattico, sarai in grado di sfruttare appieno la potenza della funzione `map()` in Python, sostituendola all’uso di cicli `for` dettagliati e alle list comprehension. Attraverso vari esempi pratici, comprenderai le diverse modalità di impiego della funzione `map()`.

Come applicare una funzione agli elementi di una lista in Python

Iniziamo con un esempio pratico. Considera una lista denominata `numeri` contenente valori numerici.

numeri = [2, 4, 3, 7]

Definisci ora una funzione chiamata `potenza_di_se()`. Questa funzione accetta un numero come argomento e restituisce quel numero elevato alla potenza di sé stesso (n**n).

In Python, l’operatore `**` è utilizzato per l’elevamento a potenza. Ad esempio, `a**b` restituisce il risultato di `a` elevato alla potenza `b`, ovvero `ab`.

def potenza_di_se(n):
    return n**n

L’obiettivo è creare una nuova lista chiamata `numeri_potenziati`, dove ogni elemento è il risultato dell’applicazione della funzione `potenza_di_se()` a ciascun elemento della lista originale `numeri`.

Utilizzo del Ciclo For

Per raggiungere questo obiettivo, è possibile utilizzare un ciclo `for`:

  • Per ogni numero nella lista `numeri`, invoca la funzione `potenza_di_se()` con il numero corrente come argomento.
  • Aggiungi il risultato di questa chiamata alla nuova lista `numeri_potenziati`.
numeri_potenziati = []

for numero in numeri:
    numeri_potenziati.append(potenza_di_se(numero))

print(numeri_potenziati)

L’output mostra che ogni numero nella lista `numeri` è stato elevato alla sua stessa potenza. Gli elementi nella lista `numeri_potenziati` risultano essere: 22, 44, 33, e 77.

Output
[4, 256, 27, 823543]

Utilizzo della List Comprehension

Un approccio più conciso è l’utilizzo delle list comprehension. Osservando il ciclo `for` precedente, possiamo identificare l’espressione di output e la lista su cui iterare.

Possiamo quindi modificare la sintassi base di una list comprehension:

nuova_lista = [<espressione di output> for elemento in iterabile]

L’espressione di list comprehension per generare la lista `numeri_potenziati` è la seguente:

numeri_potenziati = [potenza_di_se(numero) for numero in numeri]
print(numeri_potenziati)

L’output è identico a quello ottenuto con il ciclo `for`, come previsto.

Output
[4, 256, 27, 823543]

In alternativa all’uso di cicli e list comprehension, è possibile impiegare la funzione `map()` di Python, che offre una sintassi più compatta e applica la funzione specificata a tutti gli elementi di un iterabile. Iniziamo analizzando la sintassi della funzione `map()`.

Sintassi della funzione `map()` in Python

La sintassi generale per utilizzare la funzione `map()` è la seguente:

map(funzione, iterabile_1, [iterabile_2, ..., iterabile_n])

La funzione `map()` accetta almeno due argomenti: una funzione e un iterabile.

Nella sintassi precedente:

  • `funzione` rappresenta una funzione Python o, in generale, qualsiasi elemento richiamabile in Python. Ciò include funzioni definite dall’utente, classi, istanze, metodi di classe e altro ancora.
  • `iterabile` è qualsiasi struttura dati iterabile di Python valida, come una lista, una tupla o una stringa.
  • La funzione `map()` applica la funzione specificata a ciascun elemento dell’iterabile.

Qual è il valore restituito dalla funzione `map()`?

La funzione restituisce un oggetto “map”. Tale oggetto può essere convertito in una lista utilizzando la sintassi: `list(map(funzione, iterabile))`.

A seconda del caso d’uso, l’oggetto map può anche essere convertito in una tupla.

Ora che hai compreso la sintassi della funzione `map()`, passiamo agli esempi pratici.

Per seguire questo tutorial, è consigliabile utilizzare Python 3.x. In alternativa, è possibile eseguire i frammenti di codice in un editor Python online.

Come utilizzare la funzione `map()` con funzioni definite dall’utente

# 1. Come visto in precedenza, applichiamo la funzione `potenza_di_se()` a ogni numero nella lista `numeri`. Con la sintassi della funzione `map()`, è possibile passare la funzione `potenza_di_se` e la lista `numeri` come argomenti.

Nota: è importante specificare solo il nome della funzione e non la sua chiamata. Quindi, usa `potenza_di_se` e non `potenza_di_se()`. La funzione `map()` restituirà un oggetto map.

print(map(potenza_di_se, numeri))

<map object at 0x7f7d315c14d0>

Per trasformare l’oggetto map in una lista, usa la funzione `list()`, come mostrato qui:

numeri_potenziati = list(map(potenza_di_se, numeri))
print(numeri_potenziati)

Ecco l’output, in cui ogni numero in `numeri` è stato mappato a `numeronumero` nella lista `numeri_potenziati`.

Output
[4, 256, 27, 823543]

#2. Considera la seguente funzione `pollici_a_cm()` che converte i pollici in centimetri. Ricorda, 1 pollice = 2.54 cm.

def pollici_a_cm(pollici):
  return pollici * 2.54

Per convertire i valori in pollici nella lista `pollici` in centimetri, puoi utilizzare la funzione `map()`, come mostrato nel codice seguente:

pollici = [5.54, 3.4, 1, 25, 8.2]
cms = list(map(pollici_a_cm, pollici))
print(cms)

La lista `cms` contiene i valori in pollici convertiti in centimetri.

Output
[14.0716, 8.636, 2.54, 63.5, 20.828]

Come utilizzare la funzione `map()` con funzioni built-in

In questa sezione, impareremo come utilizzare `map()` con le funzioni integrate in Python.

#1. La lista `linguaggi` contiene una serie di stringhe che rappresentano linguaggi di programmazione. L’obiettivo è creare una nuova lista `linguaggi_maiuscoli` che contenga le stringhe di linguaggio di programmazione in maiuscolo.

linguaggi = ['JavaScript', 'Rust', 'Python', 'Go']

Il metodo `.upper()` delle stringhe è una funzione built-in che agisce su una stringa e ne restituisce una copia formattata in maiuscolo.

linguaggi_maiuscoli = list(map(str.upper, linguaggi))
print(linguaggi_maiuscoli)

La lista `linguaggi_maiuscoli` include le stringhe presenti in `linguaggi`, ma formattate in maiuscolo.

Output
['JAVASCRIPT', 'RUST', 'PYTHON', 'GO']

#2. La funzione `len()`, integrata in Python, accetta una sequenza come argomento e restituisce la sua lunghezza. Per determinare la lunghezza di ciascuna stringa nella lista `linguaggi`, possiamo utilizzare la funzione `map()` e applicare la funzione `len()` a ogni stringa, come illustrato di seguito.

lunghezze_linguaggi = list(map(len, linguaggi))
print(lunghezze_linguaggi)
Output
[10, 4, 6, 2]

#3. La funzione `map()` può essere usata anche con altre raccolte come le tuple.

L’esempio seguente contiene una tupla con informazioni sul numero di camere da letto, l’area e la città in cui si trova una casa.

In Python, la funzione `type()` restituisce il tipo di dati di qualsiasi oggetto Python. Per ottenere il tipo di dati di ciascun elemento di questa tupla, possiamo usare `map()` per applicare `type()` a ciascun elemento della tupla.

casa = (2, 758.5, 'Bangalore')
tipi_elementi_casa = tuple(map(type, casa))
print(tipi_elementi_casa)

L’oggetto map è stato convertito in una tupla, ma è possibile convertirlo anche in una lista o in qualsiasi altra raccolta.

Nell’output qui sotto, vediamo che i tipi di dati di 2, 758.5 e Bangalore sono stati identificati come ‘int’, ‘float’ e ‘str’, rispettivamente.

Output
(<class 'int'>, <class 'float'>, <class 'str'>)

#4. In Python, si possono importare moduli integrati e usare le funzioni definite al loro interno.

Per calcolare la radice quadrata di ogni numero nella lista `numeri`, si può usare la funzione `sqrt()` dal modulo `math`.

import math
numeri = [30, 90, 34, 45, 97]
radici_quadrate = list(map(math.sqrt, numeri))
print(radici_quadrate)
Output
[5.477225575051661, 9.486832980505138, 5.830951894845301, 6.708203932499369, 9.848857801796104]

L’output sopra risulta difficile da analizzare. Può essere utile arrotondare ogni valore della radice quadrata, ad esempio a due cifre decimali.

Come arrotondare un numero in virgola mobile in Python

Definiamo una funzione `arrotonda_a_due()` che accetta un numero in virgola mobile e lo arrotonda a due cifre decimali.

def arrotonda_a_due(numero):
  return round(numero, 2)

Ora è possibile utilizzare la funzione `map()` con la funzione `arrotonda_a_due` e la lista `radici_quadrate`.

radici_quadrate_arrotondate = list(map(arrotonda_a_due, radici_quadrate))
print(radici_quadrate_arrotondate)
Output
[5.48, 9.49, 5.83, 6.71, 9.85]

In alternativa, si possono usare funzioni `map()` annidate, dove la funzione `map()` interna calcola la lista `radici_quadrate`, e la funzione `map()` esterna effettua l’arrotondamento.

radici_quadrate_arrotondate = list(map(arrotonda_a_due, list(map(math.sqrt, numeri))))
print(radici_quadrate_arrotondate)
Output
[5.48, 9.49, 5.83, 6.71, 9.85]

Gli output sono identici in entrambi gli approcci. Tuttavia, è fondamentale garantire che il codice rimanga leggibile e gestibile, evitando un eccessivo annidamento delle funzioni come mostrato sopra.

Come utilizzare la funzione `map()` con le funzioni Lambda

Nelle sezioni precedenti, hai imparato a usare la funzione `map()` con funzioni sia built-in che definite dall’utente. Ora, scoprirai come utilizzare `map()` con le funzioni lambda, che sono funzioni anonime in Python.

A volte, può capitare di dover usare una funzione il cui corpo contiene solo una riga di codice, che viene utilizzata una sola volta senza dover essere richiamata in altre parti del programma. In questi casi, le funzioni lambda di Python possono essere molto utili.

Nota: La sintassi generale per definire una funzione lambda in Python è: `lambda argomenti: espressione`.

#1. Considera la seguente lista di stringhe. Supponiamo di voler ottenere una lista `stringhe_invertite` contenente una copia invertita di ciascuna stringa.

stringhe = ['JavaScript', 'Rust', 'Python', 'Go']

È possibile invertire una stringa in Python utilizzando lo string slicing.

Nota: Questa è una generalizzazione dell’espressione di slicing di stringhe: `str[start:stop:step]`.

  • Se i valori di inizio e fine sono omessi, la porzione inizia dall’inizio della stringa e si estende fino alla fine della stessa.
  • I valori negativi per step creano porzioni a partire dalla fine della stringa.
  • Pertanto, `str[::-1]` restituisce una copia invertita di `str`.

È possibile usare la seguente funzione lambda: `lambda x: x[::-1]` all’interno della funzione map, come mostrato di seguito.

stringhe_invertite = list(map(lambda x: x[::-1], stringhe))
print(stringhe_invertite)

Come negli esempi precedenti, convertiamo l’oggetto map in una lista. Nell’output, si osserva che ogni stringa nella lista `stringhe` è stata invertita.

Output
['tpircSavaJ', 'tsuR', 'nohtyP', 'oG']

#2. Nella sezione precedente, abbiamo calcolato la radice quadrata di ogni numero nella lista `numeri` e poi arrotondato ogni valore della radice quadrata a due cifre decimali.

Abbiamo utilizzato la funzione `arrotonda_a_due()` per questo scopo. Riscriviamo la funzione `arrotonda_a_due()` come funzione lambda, e utilizziamola con la funzione `map()`, come descritto di seguito.

radici_quadrate_arrotondate_lambda = list(map(lambda numero: round(numero, 2), radici_quadrate))
print(radici_quadrate_arrotondate_lambda)

Come si vede nell’output, il risultato è identico a quello ottenuto con la funzione `arrotonda_a_due()`.

Output
[5.48, 9.49, 5.83, 6.71, 9.85]

Come utilizzare la funzione `map()` con iterabili multipli

Negli esempi che abbiamo visto finora, abbiamo applicato una funzione a tutti gli elementi di un singolo iterabile.

Tuttavia, a volte ci si trova a lavorare con funzioni che richiedono due o più argomenti. In questi casi, ogni argomento viene di solito memorizzato in una lista o in una collezione simile.

La funzione `map()` di Python può anche essere usata con liste multiple.

#1. Si consideri la seguente funzione `area()` che accetta la lunghezza e la larghezza come input e restituisce l’area, data da lunghezza * larghezza.

def area(lunghezza, larghezza):
    return lunghezza * larghezza

Le lunghezze e le larghezze di vari rettangoli sono memorizzate in due liste separate, chiamate rispettivamente `lunghezze` e `larghezze`.

lunghezze = [4, 8, 10, 18]
larghezze = [9, 4, 6, 11]

Possiamo utilizzare la funzione `map()` per applicare la funzione `area()` alle liste precedentemente definite, passando sia `lunghezze` che `larghezze` come argomenti.

aree = list(map(area, lunghezze, larghezze))
print(aree)

Poiché la funzione `area()` richiede due argomenti, i valori di lunghezza e larghezza verranno presi dalle liste `lunghezze` e `larghezze`, rispettivamente.

Output
[36, 32, 60, 198]

#2. Il modulo `math` di Python include la funzione `log()` che consente di calcolare il logaritmo di un numero in qualsiasi base.

Nota: `log(x, base)` restituisce il valore del logaritmo di x in base specificata dal valore base, cioè logbase(x). Se la base non è specificata, il valore di default è `e` (il logaritmo calcola il logaritmo naturale).

In questo esempio:

  • La lista `x` contiene i valori per i quali calcolare il logaritmo.
  • La lista `base` contiene i valori di base da usare nel calcolo del logaritmo.
x = [2, 6, 12, 10]
base = [2, 3, 2, 5]

Possiamo utilizzare la funzione `map()` con `math.log`, la lista `x` e la lista `base` per ottenere una nuova lista `log_x` come segue.

log_x = list(map(math.log, x, base))
print(log_x)

Ecco l’output.

Output
[1.0, 1.6309297535714573, 3.5849625007211565, 1.4306765580733933]

Conclusione

Ecco un riepilogo dei concetti trattati in questo tutorial:

  • La funzione `map()` di Python accetta almeno due argomenti: una funzione e un iterabile, con la sintassi `map(funzione, iterabile(i))`.
  • La funzione può essere qualsiasi elemento richiamabile valido in Python.
  • Quando la funzione accetta k argomenti, usa la funzione `map()` con la funzione e ciascuno dei k argomenti in un iterabile separato.

Ora puoi continuare ad approfondire la tua conoscenza di Python, studiando, ad esempio, come lavorare con i set.