Módulo collections
O módulo collections estende os contêineres embutidos com tipos especializados ajustados para padrões comuns - agrupamento, contagem, filas de duas pontas e configuração em camadas.
Receita
from collections import Counter, defaultdict, deque
words = Counter("abracadabra".split())
by_len: defaultdict[int, list[str]] = defaultdict(list)
queue: deque[str] = deque(maxlen=100)Quando usar:
- Agrupar itens por chave sem
if key not in dict - Análise de frequência e contagens top-N
- Filas BFS e buffers de rolagem
- Camadas de configuração sobrepostas com
ChainMap
Exemplo de Trabalho
from collections import ChainMap, Counter, defaultdict, deque
def group_by(items: list[dict], field: str) -> dict[str, list[dict]]:
groups: defaultdict[str, list[dict]] = defaultdict(list)
for item in items:
groups[str(item[field])].append(item)
return dict(groups)
def top_n_words(text: str, n: int) -> list[tuple[str, int]]:
counts = Counter(word.lower() for word in text.split())
return counts.most_common(n)
def sliding_window(values: list[int], size: int) -> list[int]:
window: deque[int] = deque(maxlen=size)
sums: list[int] = []
for v in values:
window.append(v)
if len(window) == size:
sums.append(sum(window))
return sums
def merged_config(*maps: dict[str, object]) -> ChainMap:
return ChainMap(*maps)
if __name__ == "__main__":
rows = [{"role": "dev", "name": "a"}, {"role": "dev", "name": "b"}]
print(group_by(rows, "role"))
print(top_n_words("a b a c a b", 2))
print(sliding_window([1, 2, 3, 4, 5], 3))O que isso demonstra:
defaultdict(list)anexa sem verificações de existênciaCounter.most_commonretorna pares classificadosdeque(maxlen=...)remove automaticamente os itens mais antigos para janelas de rolagemChainMappesquisa a pilha de dicts para a primeira chave correspondente
Mergulho Profundo
Como Funciona
- defaultdict - Subclasse de dict; chamável de fábrica em
__missing__. - Counter - Subclasse de dict; chaves ausentes retornam 0; suporta
+,-,&,|. - deque - Blocos duplamente ligados; append/pop O(1) em ambas as extremidades.
- OrderedDict - Historicamente, um dict ordenado; agora em grande parte legado, exceto
move_to_end. - ChainMap - Sobreposição não destrutiva; as escritas vão apenas para o primeiro mapa.
Escolha o Tipo Certo
| Tipo | Uso |
|---|---|
deque | Fila, pilha, janela de rolagem |
Counter | Contagens de palavras, histogramas |
defaultdict | Agrupamento por, listas de adjacência |
ChainMap | Camadas de configurações com escopo |
Notas de Python
# Counter como multiconjunto
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, c=2)
print(c1 + c2)
# move_to_end em OrderedDict para ordenação estilo LRUArmadilhas
- Efeitos colaterais da fábrica defaultdict - A fábrica é chamada apenas em chaves ausentes - ainda evite trabalho pesado na fábrica. Correção: Use
list,int,setsimples. - Contagens negativas do Counter - Permitidas, mas confusas. Correção: Use
subtractcom conhecimento ou filtre os positivos. - Descarte silencioso de maxlen do deque - Os itens mais antigos desaparecem sem erro. Correção: Documente o comportamento ou verifique o comprimento.
- Surpresas de escrita do ChainMap - Atualiza apenas o primeiro dict. Correção: Copie o resultado mesclado se precisar de um dict plano.
- OrderedDict para ordenação - O dict simples já está ordenado. Correção: Use OrderedDict apenas para padrões LRU de
move_to_end.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
dict simples | Mapas simples | Boilerplate repetitivo de chave ausente |
pandas.value_counts | Colunas de DataFrame | Script apenas com biblioteca padrão |
heapq | Ordenação por prioridade | Apenas fila FIFO |
functools.lru_cache | Memoização de função | Contagem de iteráveis arbitrários |
FAQs
OrderedDict está obsoleto?
Em grande parte - o dict regular preserva a ordem de inserção. Mantenha OrderedDict para comportamentos LRU de move_to_end.
defaultdict ou setdefault?
defaultdict é mais limpo para acumulação. setdefault é bom para chaves ausentes ocasionais.
Counter pode contar objetos?
Sim, se forem hashable. Frequentemente conta strings ou tuplas extraídas de registros.
deque é thread-safe?
Append/pop são thread-safe no CPython devido ao GIL; ainda coordene operações compostas entre threads.
Como usar ChainMap para configuração de ambiente?
ChainMap(os.environ, defaults) - o ambiente substitui os padrões sem cópia.
most_common big-O?
Usa heap para top-n - eficiente quando n << chaves únicas.
namedtuple em collections?
Moveu-se para typing.NamedTuple e dataclasses - ainda disponível como collections.namedtuple.
Counter elements()?
Expande contagens para itens repetidos - útil para realimentar o multiconjunto em algoritmos.
deque vs list como fila?
Nunca use list.pop(0) em loops intensos - O(n). Sempre use deque.popleft().
Posso serializar defaultdict?
Converta para dict simples primeiro: dict(dd) - a fábrica não é preservada em JSON naturalmente.
Relacionado
- Dicionários - semântica de mapa subjacente
- heapq & Filas de Prioridade - ordenação
- Listas & Tuplas - quando deque supera list
- Escolhendo a Estrutura de Dados Certa - guia de decisão
Versões do 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+.