Boas Práticas de Coleções
Regras práticas para escolher e usar os contêineres embutidos do Python sem armadilhas de performance ou dívidas de legibilidade.
Como Usar Esta Lista
- Aplique durante a revisão de código em módulos com muitos dados.
- Revise quando a análise de performance (profiling) mostrar comportamento O(n) inesperado.
- Combine com type hints (
dict[str, int]) para contratos mais claros. - Use como checklist de integração para código de pipeline de dados.
A - Seleção
- Escolha
dictpara busca por chave,setpara pertinência,listpara sequências ordenadas. Documente escolhas não óbvias. - Use
dequepara filas FIFO/LIFO em vez delist.pop(0). O(1) vs O(n) no início. - Use
heapqpara escalonamento de prioridade;bisectpara inserções ordenadas. Nãosorted()a cada inserção. - Opte por pandas 2.2+ ou Polars 1.x em escala tabular, não dicts aninhados de listas. Operações de coluna e junções.
- Prefira
Counteredefaultdictem vez de boilerplate manual de verificação de chave. Menos ramificações, intenção mais clara.
B - Correção
- Nunca use listas ou dicts mutáveis como chaves de dict ou elementos de set. Use tupla, frozenset ou dataclass congelada.
- Copie superficialmente estruturas aninhadas com
copy.deepcopyquando a independência for necessária.dict.copy()compartilha listas internas. - Trate a ordem de iteração do set como não especificada. Use
sorted(s)apenas para exibição estável. - Valide a unicidade antes de inverter um dict
{v: k}. Valores colidentes são sobrescritos silenciosamente. - Use
getoutry/except KeyErrorintencionalmente.d[k]quando a chave deve existir;getquando é opcional.
C - Performance e Memória
- Construa
setuma vez para pertinência repetida em loops. Evitein listO(n) em caminhos críticos. - Use expressões geradoras alimentando
sum/any/maxpara grandes fluxos. Evite materializar listas de um milhão de itens. - Considere
array.arrayou bytes para buffers numéricos/binários compactos. Não lista de inteiros para protocolos de rede. - Analise a performance antes de trocar
listpor estruturas exóticas. Pequenosnfavorecem a simplicidade. - Evite
keys()repetidos, exceto se estiver mutando durante a iteração. Uselist(d)ao deletar durante o loop.
D - Legibilidade
- Use compreensões de dict/set para transformações com filtros opcionais. Mais claro que loops manuais.
- Nomeie tipos em hints:
dict[str, list[Event]], nãodictpuro. Estruturas autoexplicativas. - Use
NamedTupleou dataclass em vez de indexação de tupla posicional para registros.row[3]obscurece o significado. - Prefira a mesclagem
|para sobreposições de configuração imutáveis (3.9+).base | overrideslê da esquerda para a direita. - Desduplicação que preserva a ordem:
list(dict.fromkeys(items)). Linha única idiomática.
E - Serialização e APIs
- APIs JSON usam apenas dict/list/str/int/float/bool/None nas fronteiras. Converta sets/tuplas para listas para JSON.
- Não confie na ordem do dict para igualdade semântica entre sistemas. Compare como mapeamentos, não listas de chaves.
- Congele dicts de configuração na inicialização ao passá-los por camadas.
MappingProxyTypeou objeto de configurações tipado. - Documente semânticas de contêiner vazio -
[]vsNone. Chamadores não devem adivinhar ausente vs vazio. - Use modelos Pydantic 2 nas fronteiras HTTP; dicts puros dentro da lógica de domínio crítica quando apropriado.
FAQs
Quando OrderedDict ainda é justificado?
Padrões LRU move_to_end. O dict regular lida com a ordem de inserção caso contrário.
list ou tuple no retorno da API?
Tupla para pacotes pequenos fixos; lista ao retornar coleção homogênea de tamanho variável.
Devo sempre usar slots?
__slots__ para milhões de objetos pequenos de campo fixo. Prematuro para registros de aplicativos típicos.
Counter vs defaultdict(int)?
Counter adiciona operadores multiset e most_common - prefira para trabalho de frequência.
Como evitar surpresas de serialização com defaultdict?
Converta para dict(defaultdict) antes do JSON - a fábrica não é serializada.
Compreensões são sempre pythonicas?
Sim para transformações de map/filter. Mude para loop para efeitos colaterais ou ramificações complexas.
dict vs dataclass para registros?
dataclass/Pydantic para objetos de domínio com comportamento; dict para passagem de JSON ou chaves dinâmicas.
Quando usar ChainMap?
Busca de configuração em camadas sem cópia - env sobre padrões. Achate ao persistir.
Vale a pena usar frozenset?
Quando um conjunto de tags deve ser uma chave de dict ou entrada de cache - caso contrário, use set puro.
Maior erro com coleções?
Busca linear em lista dentro de loop - corrija com índice de set/dict construído uma vez.
Relacionados
- Escolhendo a Estrutura de Dados Certa - guia de decisão
- Noções Básicas de Estruturas de Dados - exemplos introdutórios
- Imutabilidade e Hashability - regras de hash
- Módulo collections - tipos especializados
Versões da Stack: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.