- In Python non esiste il tradizionale switch, ma può essere efficacemente emulato con istruzioni condizionali e dizionari.
- A partire da Python 3.10, il nuovo costrutto match-case aumenta la potenza e la leggibilità sostituendo il classico switch-case.
- Diverse tecniche consentono di implementare la logica a scelta multipla in Python, adattandosi a diversi scenari e versioni del linguaggio.

Ti sei mai chiesto come gestire più condizioni in Python in modo semplice ed efficiente? Quando hai lavorato con linguaggi come C, Java o JavaScript, hai sicuramente utilizzato il famoso scatola dell'interruttore scegliere tra diverse opzioni in base al valore di una variabile. Tuttavia, in Python, questo meccanismo classico non esisteva... fino a poco tempo fa. Naturalmente, mentre gli sviluppatori hanno dovuto cercare alternative per anni, il linguaggio ora offre una soluzione moderna e potente.
Questo articolo è la guida definitiva per capire come utilizzare l'equivalente switch in Python., scopri le alternative più robuste nelle versioni precedenti, chiarisci perché non è stato incorporato nelle sue fasi iniziali e impara a scrivere codice più pulito e leggibile, indipendentemente dalla versione che stai utilizzando. Preparati a imparare tutti i trucchi, gli esempi e le differenze chiave nell'implementazione di più istruzioni condizionali nell'ecosistema Python.
Esiste lo switch in Python? Storia e motivi della sua assenza
Lo switch-case, presente in molti linguaggi, non è mai arrivato ufficialmente in Python fino alla versione 3.10. La ragione principale è filosofica: i creatori di Python sono sempre stati impegnati nella semplicità e nella leggibilità. Credevano che l'introduzione di una nuova sintassi switch avrebbe potuto complicare le cose, quindi se-elif-altro era sufficiente a colmare quella lacuna. Inoltre, non si è mai raggiunto un consenso sulla sintassi ideale. Di fatto, diverse proposte ufficiali (PEP 275, PEP 3103) sono state respinte per mancanza di accordo e perché molti ritenevano che le alternative esistenti fossero sufficientemente chiare e convincenti.
Per anni la comunità ha compensato l'assenza di switch utilizzando catene di istruzioni condizionali e dizionari. Inutile dire che l'argomento ha generato dibattiti, ma lungi dall'essere uno svantaggio insormontabile, questi approcci si sono dimostrati flessibili e altamente adattabili. Tuttavia, con l'aumentare della complessità dei progetti, è emersa sempre più la necessità di una soluzione più elegante.
Cos'è un case switch e a cosa serve?
El scatola dell'interruttore È una struttura di controllo utilizzata in molti linguaggi per eseguire diversi blocchi di codice in base al valore di una variabile o di un'espressione. In altre parole, permette di selezionare un'opzione tra le numerose possibili in modo chiaro e diretto, evitando infinite catene di istruzioni condizionali.
Esempi di utilizzo tipici sarebbero: visualizzare il nome di un giorno della settimana in base a un numero, assegnare voti, scegliere operazioni in base all'input dell'utente, ecc. In linguaggi come C o Java, la sua sintassi è semplice:
switch(valor) {
case 1:
// acción
break;
case 2:
// otra acción
break;
default:
// acción por defecto
}
In Python questa struttura classica non esisteva fino a poco tempo fa, quindi gli sviluppatori hanno dovuto essere creativi per ottenere lo stesso risultato.
L'arrivo dello switch in Python: l'istruzione match-case (da Python 3.10)
Con il rilascio della versione 3.10, Python ha incorporato una funzionalità attesa da tempo: l'istruzione match-case. Sebbene la sua sintassi ricordi il tradizionale switch-case, è in realtà molto più potente, poiché introduce corrispondenza di modelli (pattern matching), che consente di confrontare non solo valori semplici, ma anche strutture complesse, tuple, classi, elenchi, dizionari, ecc.
Il match-case di Python è scritto in questo modo:
def ejemplo_switch(x):
match x:
case 1:
return "uno"
case 2:
return "dos"
case _:
return "desconocido"
Il trattino basso (_) funge da carattere jolly ed è l'equivalente di difetto In altri linguaggi, viene eseguito quando non esiste alcuna corrispondenza con un pattern precedente.
Perché è così potente? Poiché è possibile ricevere modelli complessi, catturare variabili, aprire tuple o oggetti e persino utilizzare le guardie per aggiungere condizioni extra dopo il caso:
match dato:
case (a, b) if a > b:
print("El primer elemento es mayor que el segundo")
case (a, b):
print(f"Valores: {a}, {b}")
Inoltre, in Python 3.10 e versioni successive, questa struttura migliora la leggibilità, la manutenibilità e la scalabilità del codice, soprattutto quando si gestiscono molti casi.
Alternative per passare a Python per le versioni precedenti
Prima dell'arrivo di custodia per fiammiferi, gli sviluppatori propongono alternative altrettanto valide. I due più comuni sono l'uso di catene if-elif-else e la mappatura tramite dizionariDiamo un'occhiata più da vicino:
1. Utilizzo di if-elif-else
La soluzione più diretta e semplice da comprendere è quella di concatenare le condizioni utilizzando if, elif ed else. In questo modo, è possibile coprire tutti i possibili valori di una variabile ed eseguire il blocco di codice corrispondente. Ad esempio, per visualizzare il giorno della settimana in base a un numero:
dia = 4
if dia == 1:
print('lunes')
elif dia == 2:
print('martes')
elif dia == 3:
print('miércoles')
elif dia == 4:
print('jueves')
elif dia == 5:
print('viernes')
elif dia == 6:
print('sábado')
elif dia == 7:
print('domingo')
else:
print('error')
Vantaggi di questo approccio:
- Codice semplice e facilmente leggibile.
- Non hai bisogno di altre strutture speciali: è Python puro.
- Si può usare qualsiasi tipo di confronto, non solo l'uguaglianza.
Svantaggi della scala if-elif-else:
- Tendenza al codice ripetitivo. È necessario ripetere la variabile a ogni confronto, il che genera molto testo inutile se si hanno molti casi.
- Meno efficiente quando le condizioni sono numerose. Se il caso è alla fine, prima di arrivare vengono valutati tutti i casi precedenti.
- Difficoltà nell'aggiungere o rimuovere casi in modo dinamico.
2. Utilizzo di dizionari per simulare lo switch-case
Un modo molto Python per simulare gli switch è quello di utilizzare i dizionari. L'idea è semplice: si associa ogni possibile valore (chiave) alla funzione o azione corrispondente (valore). Quindi, si cerca nel dizionario per ottenere la funzione ed eseguirla:
def lunes():
print('lunes')
def martes():
print('martes')
def error():
print('error')
switch_semana = {
1: lunes,
2: martes,
# ... otros días ...
}
dia = 8
switch_semana.get(dia, error)()
Vantaggi di questo metodo:
- Codice compatto e facilmente estensibile.
- Accesso molto rapido alla funzione giusta. Il dizionario utilizza l'hashing, quindi la ricerca è quasi istantanea.
- Consente di assegnare la stessa funzione a più tasti (ad esempio, per raggruppare i casi).
- L'interruttore può essere modificato durante l'esecuzione.
Svantaggi:
- Richiede la definizione preventiva di tutte le funzioni associate, il che può risultare macchinoso per le azioni semplici.
- Consente confronti solo per uguaglianza (non funziona per intervalli, range, ecc.).
- Non è destinato ai casi con logica condizionale più complessa all'interno di ogni selezione.
Differenza tra if-elif-else e switch (o match-case)
Il funzionamento interno di una catena if-elif-else è diverso da quello di uno switch. In if-elif-else, le condizioni vengono valutate una alla volta, dall'alto verso il basso, finché la prima condizione non è vera. Pertanto, se il valore cercato è all'inizio, l'esecuzione è rapida; se è alla fine, richiederà più tempo.
Gli switch tradizionali (e il dizionario come alternativa in Python) invece utilizzano spesso tabelle di ricerca, quindi l'accesso è più uniforme, indipendentemente dal numero di istanze o dalla loro posizione. custodia per fiammiferi e dizionari, il tempo di accesso è molto più omogeneo.
Quando scegliere ciascuna alternativa?
Non esiste una soluzione universale: lo strumento migliore dipende dal problema specifico.
- Per un numero limitato di condizioni o una logica complessa in ogni ramo, if-elif-else è la scelta più semplice. Permette qualsiasi confronto ed è molto flessibile.
- Quando si hanno molti casi e ognuno di essi esegue semplicemente un'azione specifica, è opportuno affidarsi ai dizionari. Il codice è più pulito, scalabile e più facile da gestire.
- Se utilizzi Python 3.10 o versione successiva, custodia per fiammiferi È la scelta migliore per chiarezza e potenza. Permette di unire l'eleganza dell'interruttore alla potenza dell'abbinamento di pattern su strutture complesse.
Pensa sempre alla leggibilità, alle prestazioni e alla manutenibilità del tuo codice.
Esempi pratici di utilizzo di switch in Python e delle sue alternative
Diamo un'occhiata ad alcuni esempi in cui ciascuna di queste alternative viene applicata, dalla complessità minore a quella maggiore:
Esempio 1: Calcola il voto in base a un punteggio
# Usando if-elif-else
puntuacion = 85
if puntuacion >= 90:
print('Sobresaliente')
elif puntuacion >= 80:
print('Notable')
elif puntuacion >= 70:
print('Bien')
else:
print('Insuficiente')
Questo caso è perfetto per utilizzare le istruzioni condizionali, poiché si lavora con intervalli, non con valori fissi.
Esempio 2: Visualizzare il giorno della settimana in base al numero (con dizionario)
# Definición de funciones para cada día
def lunes():
print('lunes')
def martes():
print('martes')
def miercoles():
print('miércoles')
def jueves():
print('jueves')
def viernes():
print('viernes')
def sabado():
print('sábado')
def domingo():
print('domingo')
def error():
print('error')
switch_semana = {
1: lunes,
2: martes,
3: miercoles,
4: jueves,
5: viernes,
6: sabado,
7: domingo
}
dia = 8
switch_semana.get(dia, error)()
Esempio 3: utilizzo di match-case per selezionare un'operazione aritmetica
operacion = 'suma'
a = 10
b = 5
match operacion:
case 'suma':
print(a + b)
case 'resta':
print(a - b)
case 'multiplicacion':
print(a * b)
case 'division':
print(a / b)
case _:
print('Operación no válida')
Come puoi vedere, la sintassi è semplice e molto chiara. Il trattino basso indica il caso predefinito.
Esempio avanzato: corrispondenza di modelli con match-case
Il grande punto di forza del match-case è la sua capacità di lavorare con modelli complessi. Ad esempio, è possibile analizzare tuple, elenchi, dizionari, oggetti, ecc.
punto = (3, 5)
match punto:
case (0, 0):
print('Origen')
case (0, y):
print(f'Eje Y en {y}')
case (x, 0):
print(f'Eje X en {x}')
case (x, y):
print(f'Coordenadas X={x}, Y={y}')
Puoi anche usare la clausola if (guardia) per aggiungere condizioni aggiuntive a ciascun caso.
Differenze di prestazioni tra if-elif-else, dizionari e match-case
Nella maggior parte dei casi, la differenza di prestazioni è trascurabile per gli script normali. Tuttavia, quando le alternative sono numerose, i dizionari e la distinzione tra maiuscole e minuscole possono essere più efficienti, poiché riducono il numero di confronti. Tuttavia, il fattore più importante è solitamente il leggibilità e manutenibilità del codice, piuttosto che micro-ottimizzazioni che raramente fanno la differenza nei progetti reali.
Utilizzare la tecnica che rende il codice più chiaro ed evita errori.
Soluzioni creative: classi e gestori di contesto per emulare lo switch
Alcuni sviluppatori hanno creato classi specializzate che consentono di emulare il comportamento classico degli switch, incluse opzioni avanzate come l'aggiunta rompere per controllare l'esecuzione di casi successivi, raggruppare casi, personalizzare confronti o abilitare la modalità rigorosa per garantire che venga eseguito un solo ramo.
Ad esempio, è possibile implementare un gestore di contesto personalizzato che utilizzi una sintassi molto simile a quella di altri linguaggi:
class switch:
def __init__(self, variable, comparator=None, strict=False):
self.variable = variable
self.matched = False
self.matching = False
if comparator:
self.comparator = comparator
else:
self.comparator = lambda x, y: x == y
self.strict = strict
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
pass
def case(self, expr, break_=False):
if self.strict:
if self.matched:
return False
if self.matching or self.comparator(self.variable, expr):
if not break_:
self.matching = True
else:
self.matched = True
self.matching = False
return True
else:
return False
else:
if self.matching or self.comparator(self.variable, expr):
if not break_:
self.matching = True
else:
self.matched = True
self.matching = False
return True
else:
return False
def default(self):
return not self.matched and not self.matching
L'utilizzo di questa classe consente una sintassi come questa:
dia = 4
with switch(dia) as s:
if s.case(1, True): print('lunes')
if s.case(2, True): print('martes')
if s.case(3, True): print('miércoles')
if s.case(4, True): print('jueves')
if s.case(5, True): print('viernes')
if s.case(6, True): print('sábado')
if s.case(7, True): print('domingo')
if s.default(): print('error')
Vantaggi di questa soluzione? Ha una sintassi molto familiare per chi proviene da altri linguaggi e consente personalizzazioni avanzate, come l'utilizzo di qualsiasi funzione di confronto, il raggruppamento dei casi, l'esecuzione di più rami o solo di uno, ecc. Lo svantaggio è che di solito è più lento e richiede l'importazione o la definizione della classe speciale.
Utilizzo delle funzioni lambda per semplificare le azioni sui dizionari
Spesso non è necessario definire funzioni separate per ogni azione; è possibile utilizzare funzioni anonime (lambda). Ciò è particolarmente pratico quando l'azione da eseguire è semplice:
switch_operaciones = {
'sumar': lambda a, b: a + b,
'restar': lambda a, b: a - b,
'multiplicar': lambda a, b: a * b
}
operacion = 'sumar'
resultado = switch_operaciones.get(operacion, lambda a, b: None)(5, 3)
print(resultado)
Ciò rende il codice compatto e facile da espandere senza perdere chiarezza.
Casi d'uso avanzati: corrispondenza di modelli in Match-Case
Frase custodia per fiammiferi Python 3.10 va ben oltre la semplice copia del classico switch-case. La sua vera potenza risiede nel corrispondenza di modelli strutturaliAd esempio, consente di distinguere facilmente tra diverse strutture dati, classi personalizzate, scomporre oggetti e catturare sottoelementi.
Esempio con liste e tuple:
datos =
match datos:
case :
print('Lista con 1, 2, 3')
case :
print('Lista que empieza con 1')
case _:
print('Otra lista')
Esempio con oggetti (ipotizzando una classe Point):
class Punto:
def __init__(self, x, y):
self.x = x
self.y = y
p = Punto(2, 3)
match p:
case Punto(x=0, y=0):
print('Origen')
case Punto(x, y):
print(f'Coordenadas: {x} {y}')
Questo meccanismo consente di scrivere codice altamente espressivo che si adatta a strutture complesse senza perdere leggibilità.
Aspetti da considerare durante la migrazione del codice: compatibilità e best practice
Non tutti i progetti possono permettersi di utilizzare subito il metodo match-case. Se lavori in ambienti con versioni precedenti di Python (ad esempio, 3.8 o 3.9), dovrai optare per i dizionari. Quando potrai aggiornare alla versione 3.10 o successiva, sfrutta la potenza e la chiarezza del pattern matching, soprattutto nei progetti in cui la logica di selezione multipla è essenziale.
Ricorda:
- Scegli l'opzione che offre la migliore leggibilità, flessibilità e facilità di manutenzione.
- Nei problemi molto semplici (alcuni casi), if-elif-else è solitamente sufficiente e più diretto.
- Per tabelle di selezione di grandi dimensioni, utilizzare dizionari e funzioni.
- Per strutture complesse o per sfruttare appieno il Python moderno, scegli match-case.
Un piccolo trucco: è possibile convertire le funzioni esistenti in modo che accettino dizionari di azioni, rendendo ancora più semplice la transizione tra gli approcci.
Suggerimenti per l'ottimizzazione e la progettazione per un codice Python più pulito
Non commettere l'errore di progettare infinite catene di condizioni solo per imitare il classico switch. Considera ogni caso specifico e valuta quale struttura di controllo aggiunge il massimo valore al contesto del tuo programma. Ricorda che Python attribuisce grande importanza alla chiarezza, quindi evita di complicare eccessivamente il codice se puoi ottenere lo stesso risultato più facilmente.
Un consiglio importante: Quando si utilizzano i dizionari, utilizzare la funzione get() per evitare errori se la chiave non esiste e poter quindi definire in modo elegante un caso predefinito.
Confronto con altre lingue e considerazioni finali
In alcuni linguaggi, come C, C++ o Java, gli switch consentono solo di confrontare valori semplici (interi, stringhe) e forniscono scarso valore per strutture complesse. Python fa un ulteriore passo avanti: prima offre alternative versatili (if-elif-else, dizionari), e ora apre le porte a una logica avanzata senza sforzi aggiuntivi. La chiave è sfruttare i vantaggi di ogni versione e non forzarsi a imitare altre sintassi se il problema richiede una soluzione diversa.
Se hai appena iniziato con Python o provieni da altri linguaggi, non preoccuparti se non riesci a trovare la parola chiave switch nel manuale. Valuta tutte le possibilità disponibili e scegli quella più adatta al tuo contesto e alle tue esigenze.
Gestire più alternative in Python non è mai stato così facile e potente. Ora capisci le ragioni dell'assenza (e del successivo arrivo) dello switch, come simularlo efficacemente in qualsiasi versione e come sfruttare al meglio la nuova istruzione match-case. Che tu debba scegliere tra una mezza dozzina di opzioni, manipolare strutture complesse, seguire le best practice o preoccuparti delle prestazioni, hai a disposizione alternative robuste, eleganti e flessibili. Che il tuo codice sia per script rapidi o applicazioni complesse, Python ti offre gli strumenti per scriverlo in modo chiaro, rapido e semplice.
Sommario
- Esiste lo switch in Python? Storia e motivi della sua assenza
- Cos'è un case switch e a cosa serve?
- L'arrivo dello switch in Python: l'istruzione match-case (da Python 3.10)
- Alternative per passare a Python per le versioni precedenti
- Differenza tra if-elif-else e switch (o match-case)
- Quando scegliere ciascuna alternativa?
- Esempi pratici di utilizzo di switch in Python e delle sue alternative
- Esempio avanzato: corrispondenza di modelli con match-case
- Differenze di prestazioni tra if-elif-else, dizionari e match-case
- Soluzioni creative: classi e gestori di contesto per emulare lo switch
- Utilizzo delle funzioni lambda per semplificare le azioni sui dizionari
- Casi d'uso avanzati: corrispondenza di modelli in Match-Case
- Aspetti da considerare durante la migrazione del codice: compatibilità e best practice
- Suggerimenti per l'ottimizzazione e la progettazione per un codice Python più pulito
- Confronto con altre lingue e considerazioni finali