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_padrao e usar TypeVar('T').
  • Deve aceitar lista: list[T] e padrao: T e retornar T.
  • 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

  1. Importamos TypeVar do módulo typing e criamos T = TypeVar('T').
  2. Definimos a função com lista: list[T] e padrao: T, retornando T.
  3. Verificamos se a lista não está vazia com if lista:.
  4. Se não estiver vazia, retornamos lista[0]; caso contrário, retornamos padrao.
  5. 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 list sem parâmetro: def f(lista: list, padrao: T) -> T: — mypy não consegue inferir o tipo dos elementos.
  • Retornar padrao quando a lista não está vazia — lógica invertida.
  • Não anotar o retorno como T — mypy pode inferir object, 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