Structural Pattern Matching: a Estrutura match em Python
A partir da versão 3.10, o Python introduziu uma funcionalidade chamada structural pattern matching (correspondência de padrões estruturais). Essa funcionalidade envolve o uso da palavra-chave match
, que permite comparar uma expressão com um determinado padrão. Se a expressão corresponder ao padrão, ações específicas são executadas. Nesse sentido, a estrutura match
é semelhante à estrutura if
/elif
/else
, que executa determinadas ações com base em uma condição. No entanto, a funcionalidade match
é mais ampla, pois também permite extrair dados de tipos compostos e aplicar ações a diferentes partes de objetos.
A estrutura match tem a seguinte definição:
match expressão:
case padrão_1:
ação_1
case padrão_2:
ação_2
...
case padrão_N:
ação_N
case _:
ação_padrão
Após a palavra-chave match
, vem a expressão a ser comparada. Em seguida, após os dois pontos, estão as declarações case
. Cada case
especifica um padrão com o qual a expressão do match
é comparada. Após o padrão, e seguido de dois pontos, estão as ações a serem executadas se houver correspondência.
A estrutura match
compara sequencialmente a expressão com os padrões nos blocos case
. Se algum padrão corresponder à expressão, as instruções desse bloco case são executadas.
Como padrões, podem ser utilizados dados de tipos primitivos, bem como sequências de elementos e objetos de classes.
Vamos primeiro considerar uma situação em que os padrões são literais de tipos primitivos. Por exemplo, exibiremos uma mensagem de saudação dependendo do idioma:
def print_hello(language):
match language:
case "portuguese":
print("Olá")
case "english":
print("Hello")
case "german":
print("Hallo")
print_hello("english") # Hello
print_hello("german") # Hallo
print_hello("portuguese") # Olá
Aqui, a função print_hello
recebe o parâmetro language
, que representa o idioma selecionado. Dentro da função, a estrutura match
compara o valor da variável language
. Nos blocos case
, são definidos os padrões—strings com as quais language
é comparado.
Por exemplo, ao chamar print_hello("english")
, o parâmetro language
é igual a "english", então a estrutura match seleciona o seguinte bloco case:
case "english":
print("Hello")
Observe que os blocos case
são indentados em relação ao início da estrutura match
. As instruções dentro de cada bloco case
também são indentadas em relação ao case
. Se um bloco case
tiver apenas uma instrução, ela pode ser colocada na mesma linha que o operador case
:
def print_hello(language):
match language:
case "portuguese": print("Olá")
case "english": print("Hello")
case "german": print("Hallo")
Se a expressão do match
não corresponder a nenhum dos padrões case
, nenhum dos blocos case
é executado.
Se for necessário executar ações padrão quando não houver correspondência (isto é, se nenhum dos padrões case
corresponder à expressão match
), pode-se utilizar o padrão _
(sublinhado):
def print_hello(language):
match language:
case "portuguese": print("Olá")
case "english": print("Hello")
case "german": print("Hallo")
case _: print("Language not supported")
print_hello("english") # Hello
print_hello("spanish") # Undefined
Se nenhum dos padrões case
corresponder ao valor de language
, o bloco a seguir será executado:
case _: print("Language not supported")
Também é possível definir um bloco case
que permite comparar com múltiplos valores ao mesmo tempo. Nesse caso, os valores são separados por uma barra vertical |
:
def print_hello(language):
match language:
case "portuguese":
print("Olá")
case "american english" | "british english" | "english":
print("Hello")
case _:
print("Undefined")
print_hello("english") # Hello
print_hello("american english") # Hello
print_hello("spanish") # Undefined
Nesse caso, o padrão case "american english" | "british english" | "english"
corresponde a três valores diferentes.
Da mesma forma, é possível comparar expressões com dados de outros tipos. Por exemplo:
def operation(a, b, code):
match code:
case 1:
return a + b
case 2:
return a - b
case 3:
return a * b
case _:
return 0
print(operation(10, 5, 1)) # 15
print(operation(10, 5, 2)) # 5
print(operation(10, 5, 3)) # 50
print(operation(10, 5, 4)) # 0
Aqui, a função operation
recebe dois números e um código de operação. A estrutura match compara o código da operação com valores específicos e, dependendo do valor, realiza uma determinada operação nos números. Por exemplo, se code
for igual a 1, o seguinte bloco case
é executado:
case 1:
return a + b
Este bloco case retorna a soma dos números a
e b
. De forma semelhante, se code = 2
, a diferença é retornada, e se code = 3
, o produto dos números é retornado. Em todos os outros casos, a função retorna 0
.
Documentação oficial: