Execução condicional simplificada com match
A instrução match foi introduzida no Python 3.10 como uma forma de simplificar a execução de condicionais e tornar os códigos mais legíveis. Ela permite escrever lógicas condicionais usando padrões em vez de strings ou valores. Quando foi introduzida, uma preocupação frequente dos desenvolvedores do Python era sobre a facilidade de explicar esse recurso. Este será o objetivo deste post. Vamos a um exemplo.
def diga_oi(nome: str) -> None:
match nome:
case "Ana":
print(f"Bom dia, Ana!")
case "Maria":
print(f"Olá, Maria!")
case _:
print(f"Oi, {nome}!")
diga_oi("Felipe") # Resultado: Oi, Felipe!
diga_oi("Maria") # Resultado: Olá, Maria!
diga_oi("Ana") # Bom dia, Ana!
Vamos entender como esse código funciona. A expressão do match é avaliada uma vez. O valor da expressão é comparado com os valores de cada caso (case). Se houver uma correspondência, o bloco de código associado é executado. O caractere sublinhado _ funciona como um coringa. Ou seja, ele é um bloco de código executado quando não houver outras correspondências.
Sintaxe
A sintaxe match-case demonstrada acima é baseada em correspondência estrutural de padrões:
match sujeito:
case padrao1:
# Bloco de código se o padrão1 coincidir
case padrao2:
# Bloco de código se o padrão2 coincidir
case _:
# Caso padrão (wildcard, coringa) se nenhum outro padrão coincidir
O valor _ sempre vai corresponder, portanto, é importante colocá-lo como o último caso para que ele se comporte como um caso padrão.
O poder da instrução match-case está em sua capacidade de corresponder uma variedade de tipos de dados, incluindo strings, sequências, mapeamentos e classes personalizadas.
Outro exemplo
def verifica_numero(x):
match x:
case 10:
print("O número é 10")
case 20:
print("O número é 20")
case _:
print("O número é diferente de 10 e de 20")
verifica_numero(10) # Resultado: O número é 10
verifica_numero(30) # Resultado: O número é diferente de 10 e de 20
Neste exemplo, a função verifica_numero(x) usa uma instrução match-case para comparar o valor de x com os valores 10 e 20. Se x for igual a 10, ela imprime “O número é 10”. Se x for igual a 20, ela imprime “O número é 10”. Se x for diferente das duas condições testadas, o bloco do coringa _ é executado.
match com operador OR
Veja uma modificação mais enxuta da função acima usando o comando OR (|). Ela verifica se um número corresponde a 10, 20 ou 30. Para esses casos, ela imprime “Certo”. Caso um número não corresponda a esses valores, a função imprime “Errado”.
def verifica_numero(x):
match x:
case 10 | 20 | 30:
print("Correto")
case _:
print("Errado")
verifica_numero(10) # Resultado: Correto
verifica_numero(50) # Resultado: Errado
match com sequências
A instrução match-case é particularmente poderosa ao trabalhar com sequências como listas ou tuplas. Veja um exemplo com listas:
def verifica_formato_de_lista(dado):
match dado:
case [x, y]:
# Uma lista com dois elementos
print(f"Lista de dois elementos: {x}, {y}")
case [x, y, z]:
# Uma lista com três elementos
print(f"Lista de três elementos: {x}, {y}, {z}")
case _:
print("Formado desconhecido")
verifica_formato_de_lista([2, 3]) # Resultado: Lista de dois elementos: 2, 3
verifica_formato_de_lista([2, 3, 4]) # Resultado: Lista de três elementos: 2, 3, 4
verifica_formato_de_lista([2, 3, 4, 5]) # Resultado: Formado desconhecido
match com if
Também podemos combinar match com if para condicionais complexos. No exemplo abaixo, o condicional if é usado em combinação com o operador OR (|):
def verifica_data(dia, mes):
match dia:
case 1 | 2 | 3 | 4 | 5 if mes == 1:
print("Dia da semana em Janeiro")
case 1 | 2 | 3 | 4 | 5 if mes == 2:
print("Dia da semana em Fevereiro")
case _:
print("Dia desconhecido")
verifica_data(3, 1) # Dia da semana em Janeiro
verifica_data(6, 3) # Dia desconhecido
A função acima recebe dois argumentos, dia e mês. Se o dia e o mês fornecidos correspondem ao case1 ou case2, a mensagem correspondente será impressa. Caso contrario, o bloco coringa é executado.