Desafio Python
Função genérica com TypeVar e mypy
Enunciado
Implemente uma função genérica primeiro_ou_padrao que recebe uma lista de qualquer tipo T e um valor padrão do mesmo tipo T. Se a lista não estiver vazia, retorna o primeiro elemento; caso contrário, retorna o valor padrão. Use TypeVar para expressar o genérico e anote corretamente. Depois, teste com listas de inteiros e strings.
Requisitos
- A função deve se chamar
primeiro_ou_padraoe usarTypeVar('T'). - Deve aceitar
lista: list[T]epadrao: Te retornarT. - Se a lista tiver elementos, retornar o primeiro; senão, retornar
padrao. - O programa deve imprimir resultados para uma lista de inteiros e uma de strings.
Código inicial
from typing import TypeVar
T = TypeVar('T')
def primeiro_ou_padrao(lista, padrao):
# complete aqui
pass
print(primeiro_ou_padrao([1, 2, 3], 0))
print(primeiro_ou_padrao([], 0))
print(primeiro_ou_padrao(["a", "b"], "z"))
print(primeiro_ou_padrao([], "z"))
Saída esperada
1
0
a
z
Ver dica
Use if lista: para verificar se a lista não está vazia e retorne lista[0] ou padrao.
Mostrar solução
from typing import TypeVar
T = TypeVar('T')
def primeiro_ou_padrao(lista: list[T], padrao: T) -> T:
if lista:
return lista[0]
return padrao
print(primeiro_ou_padrao([1, 2, 3], 0))
print(primeiro_ou_padrao([], 0))
print(primeiro_ou_padrao(["a", "b"], "z"))
print(primeiro_ou_padrao([], "z"))
Passo a passo
- Importamos
TypeVardo módulotypinge criamosT = TypeVar('T'). - Definimos a função com
lista: list[T]epadrao: T, retornandoT. - Verificamos se a lista não está vazia com
if lista:. - Se não estiver vazia, retornamos
lista[0]; caso contrário, retornamospadrao. - Chamamos a função com listas de inteiros e strings, imprimindo os resultados.
Por que funciona
TypeVar permite que a função seja genérica: o mypy infere que para [1,2,3] e 0, T é int; para ["a","b"] e "z", T é str. Assim, o retorno é do mesmo tipo dos elementos. Isso garante segurança de tipos sem sacrificar a flexibilidade.
Erros comuns
- Esquecer de importar
TypeVar— NameError. - Usar
listsem parâmetro:def f(lista: list, padrao: T) -> T:— mypy não consegue inferir o tipo dos elementos. - Retornar
padraoquando a lista não está vazia — lógica invertida. - Não anotar o retorno como
T— mypy pode inferirobject, perdendo precisão.
Outra forma de resolver
Usar list[T] | None e tratar o None como lista vazia:
def primeiro_ou_padrao(lista: list[T] | None, padrao: T) -> T:
if lista:
return lista[0]
return padrao
Útil se a lista puder ser None.
Saída esperada
1
0
a
z