6 casi d’uso in Python in cui * e ** sono utili

6 use cases in Python where * and ** are useful.

Spiegato con esempi

Foto di Szabolcs Toth su Unsplash

Se mai dovessi consultare la documentazione di una libreria Python, è inevitabile notare l’uso di * o ** in diversi luoghi.

Ma cosa fanno (* e **)?

Impareremo 7 casi d’uso in cui * e ** sono utili, compresi i casi che si notano nella documentazione.

I casi d’uso sono meglio spiegati con esempi, quindi passiamo subito a quelli.

1. Chiamare una funzione con iterable

Supponiamo che si definisca una funzione che richiede 5 argomenti posizionali, li somma e restituisce la somma.

# definire la funzionedef calcola_somma(a, b, c, d, e):    return a + b + c + d + e# chiamare la funzione risultato = calcola_somma(1, 4, 3, 2, 6)print(risultato)16

Se i valori passati alla funzione come argomenti sono memorizzati in un iterable (ad esempio una lista), è possibile chiamare la funzione direttamente utilizzando la lista, ma è necessario utilizzare * come mostrato di seguito:

# chiamare la funzionenumbers = [1, 4, 3, 2, 6]calcola_somma(*numbers)print(risultato)16

Se si cerca di chiamare la funzione come calcola_somma(numbers), Python si lamenta, generando un TypeError. Ciò che * fa qui è scompattare i valori nell’iterable, talvolta indicato come scompattamento degli argomenti.

È importante notare che il numero di valori nella lista numbers deve essere uguale al numero di argomenti che la funzione richiede, che in questo caso è 5. In caso contrario, otterremo un TypeError.

2. Chiamare una funzione con dizionari

Questo caso d’uso è simile al precedente. Nell’esempio precedente, la funzione ha solo argomenti posizionali. Nel caso di una funzione con argomenti di parola chiave, possiamo comunque effettuare lo scompattamento degli argomenti ma con ** invece di *.

# definire la funzionedef calcola_massa(densità, lunghezza=1, larghezza=1, altezza=1):    return densità * lunghezza * larghezza * altezza# chiamare la funzionedensità = 20massa = calcola_massa(densità, 2, 3, 5)print(massa)600

La funzione calcola la massa di un oggetto utilizzando la sua densità, lunghezza, larghezza e altezza. Supponiamo che le misure siano memorizzate in un dizionario Python. Possiamo utilizzare direttamente il dizionario per chiamare la funzione come mostrato di seguito:

# chiamare la funzionedensità = 20misure = {    "lunghezza": 2,    "larghezza": 3,    "altezza": 5}calcola_massa(densità, **misure)600

Come nel primo esempio, se proviamo a chiamarlo come calcola_massa(densità, misure), otterremo un TypeError. Questo è un altro esempio di scompattamento degli argomenti.

3. Definire una funzione con qualsiasi numero di argomenti posizionali

Si definisce una funzione che somma i valori dati, ma non si vuole porre una restrizione sul numero di valori da passare come argomenti. Invece, si vuole che sia dinamica e sommi qualsiasi numero di valori dati.

Ecco come si può definire questa funzione:

# definire la funzionedef calcola_somma(*args):    risultato = 0    for i in args:        risultato += i    return risultato

L’espressione *args impacchetta gli argomenti passati alla funzione, permettendoci di utilizzare qualsiasi numero di argomenti o un iterable per chiamare la funzione.

Ecco diversi modi per chiamare questa funzione:

# chiamata con 2 valori calcola_somma(3, 4)7# chiamata con una listamy_list = [1, 4, 5, 10, 20]calcola_somma(*my_list)40# chiamata con un valore e una listamy_list = [10, 20, 30]calcola_somma(5, *my_list)65

Nel caso in cui si utilizzi un iterabile per chiamare la funzione, è comunque necessario inserire un * durante la chiamata della funzione.

Nota sugli argomenti posizionali e per parole chiave:

Gli argomenti posizionali sono dichiarati solo da un nome. Quando una funzione viene chiamata, devono essere forniti valori per gli argomenti posizionali. Altrimenti, si otterrà un errore.

Gli argomenti per parole chiave sono dichiarati da un nome e un valore predefinito. Se non specifichiamo il valore per un argomento per parole chiave, prende il valore predefinito.

4. Definire una funzione con qualsiasi numero di argomenti per parole chiave

Questo caso d’uso è simile al caso d’uso precedente, ma creeremo una funzione che prenda argomenti per parole chiave.

# definire la funzionedef saluta(nome, **kwargs):    saluto = f"Ciao, {nome}.\n"        if kwargs:        saluto += "Ecco le cose che so di te:\n"        for key, value in kwargs.items():            saluto += f" {key.title()}: {value}\n"        return saluto

La funzione saluta le persone dato il loro nome. Se è chiamata con argomenti per parole chiave aggiuntivi di informazioni sulle persone, la funzione le stampa anche.

L’espressione **kwargs ci consente di passare qualsiasi numero di argomenti per parole chiave durante la chiamata della funzione.

Ecco diversi modi per chiamare questa funzione:

# chiamata solo con il nome (argomento posizionale)print(saluta("John"))# outputCiao, John.# chiamata con l'aggiunta di alcuni argomenti per parole chiaveprint(saluta("Jane", age=34, job="doctor", hobby="chess"))# outputCiao, Jane.Ecco le cose che so di te: Age: 34 Job: doctor Hobby: chess# chiamata con l'aggiunta di alcuni argomenti per parole chiave come dizionarioashley = {    "age": 27,    "professione": "atleta",    "hobby": "lettura"}print(saluta("Ashley", **ashley))# outputCiao, Ashley.Ecco le cose che so di te: Age: 27 Professione: atleta Hobby: lettura

Nel caso in cui passiamo gli argomenti per parole chiave come un dizionario, è necessario inserire un ** durante la chiamata della funzione.

5. Combinare i dizionari

Possiamo utilizzare ** per combinare i dizionari.

eta = {    "John": 34,    "Jane": 36}nuovi_elementi = {    "Matt": 28,    "Ashley": 24}eta = {**eta, **nuovi_elementi}print(eta){'John': 34, 'Jane': 36, 'Matt': 28, 'Ashley': 24}

In questo caso, utilizzando eta = {eta, nuovi_elementi} genererà un TypeError.

6. Imballare i valori in iterabili

Diciamo che abbiamo una lista con più valori. Vogliamo assegnare un valore da questa lista ad un’altra variabile e assegnare quelli rimanenti ad una variabile diversa. Sarà più chiaro quando andremo attraverso gli esempi qui sotto:

primo, *altri = [3, 5, 1, 10, 24]print(primo)print(altri)# output3[5, 1, 10, 24]

Il primo valore viene assegnato ad una variabile chiamata primo e quelli rimanenti sono imballati in un’altra lista chiamata altri.

Possiamo anche usarlo come mostrato nell’esempio qui sotto:

primo, *altri, ultimo = [3, 5, 1, 10, 24]print(primo)print(altri)print(ultimo)# output3[5, 1, 10]24

Questo caso d’uso potrebbe essere utile quando si lavora con funzioni che restituiscono più valori. Ecco un esempio:

# definire la funzionedef mia_funzione(a, b, c, d, e):    somma_1 = a + b    somma_2 = a + b + c    somma_3 = a + b + c + d    somma_4 = a + b + c + d + e    return somma_1, somma_2, somma_3, somma_4# chiamare la funzionefirst_sum, *other_sums = mia_funzione(1, 3, 5, 2, 6)print(first_sum)print(other_sums)# output4[9, 11, 17]

La funzione my_func restituisce una tupla con 4 valori. Il primo viene assegnato ad una variabile chiamata first_one e gli altri ad una lista chiamata other_sums.

Parole finali

Come dimostrato negli esempi che abbiamo fatto, * e ** sono molto utili in Python. Possiamo usarli per l’impacchettamento e lo scodamento degli argomenti.

Sono anche utilizzati nella definizione e nella chiamata delle funzioni per aggiungere maggiore flessibilità e versatilità.

Puoi diventare un membro di Nisoo per sbloccare l’accesso completo alla mia scrittura, oltre al resto di Nisoo. Se lo sei già, non dimenticare di iscriverti se vuoi ricevere un’email ogni volta che pubblico un nuovo articolo.

Grazie per la lettura. Per favore, fatemi sapere se avete qualche feedback.