Capítulo 39, Intermediário
Biblioteca padrão essencial
Antes de instalar um pacote, procure na biblioteca padrão. Estes são os módulos que eu uso toda semana.
Código deste capítulo: intermediario/cap39_stdlib.py
collections e itertools
O deque com maxlen é a estrutura natural para "os últimos N itens". O itertools combina e agrupa iteráveis sem criar listas intermediárias:
from collections import deque
from itertools import chain, combinations, groupby, product
ultimos = deque(maxlen=3)
for n in range(6):
ultimos.append(n)
print(list(ultimos))
print(list(chain([1, 2], [3])))
print(list(combinations("abc", 2)))
print(list(product([0, 1], repeat=2)))
vendas = [("sul", 10), ("sul", 5), ("norte", 7)]
for regiao, itens in groupby(sorted(vendas), key=lambda v: v[0]):
print(regiao, sum(valor for _, valor in itens))
[3, 4, 5]
[1, 2, 3]
[('a', 'b'), ('a', 'c'), ('b', 'c')]
[(0, 0), (0, 1), (1, 0), (1, 1)]
norte 7
sul 15
O groupby só agrupa itens consecutivos iguais, por isso o sorted antes. Esquecer isso é o erro mais comum com ele.
json
O JSON é o formato de troca de dados da internet. O ensure_ascii=False mantém os acentos legíveis, e o indent formata:
import json
dados = {"nome": "Ana", "idade": 30, "tags": ["a", "b"], "ativo": True, "nota": None}
texto = json.dumps(dados, ensure_ascii=False, indent=2)
print(texto)
volta = json.loads(texto)
print(volta == dados)
{
"nome": "Ana",
"idade": 30,
"tags": [
"a",
"b"
],
"ativo": true,
"nota": null
}
True
Repare que True virou true e None virou null. Os tipos de Python que o JSON não conhece (como datetime e Decimal) precisam ser convertidos antes.
csv
Ler CSV com DictReader dá a você dicionários com o cabeçalho como chave. Os exemplos usam io.StringIO para simular um arquivo, mas com um arquivo real você passa o objeto do open() (com newline=""):
import csv
import io
conteudo = "produto,preco\ncaneta,3.5\ncaderno,18.9\n"
leitor = csv.DictReader(io.StringIO(conteudo))
total = sum(float(linha["preco"]) for linha in leitor)
print(round(total, 2))
saida = io.StringIO()
escritor = csv.DictWriter(saida, fieldnames=["produto", "preco"], lineterminator="\n")
escritor.writeheader()
escritor.writerow({"produto": "lápis", "preco": 1.2})
print(saida.getvalue().strip())
22.4
produto,preco
lápis,1.2
datetime e fusos horários
Guarde e calcule datas com fuso horário, de preferência em UTC, e converta só na hora de mostrar. Datas "ingênuas" (sem fuso) são fonte de bugs em sistemas com mais de uma região:
from datetime import datetime, timedelta, timezone
agora = datetime(2026, 10, 6, 14, 30, tzinfo=timezone.utc)
print(agora.isoformat())
brasilia = timezone(timedelta(hours=-3))
print(agora.astimezone(brasilia).strftime("%d/%m/%Y %H:%M"))
2026-10-06T14:30:00+00:00
06/10/2026 11:30
Para fusos com nome e horário de verão, use zoneinfo.ZoneInfo("America/Sao_Paulo"). No Windows, o banco de fusos não vem com o sistema, e é preciso instalar o pacote tzdata (pip install tzdata).
re
As expressões regulares resolvem extração e troca de padrões em texto. Use strings brutas (r"...") para não duplicar as barras invertidas:
import re
texto = "Contato: ana@exemplo.com, bia@teste.org"
print(re.findall(r"[\w.]+@[\w.]+", texto))
m = re.search(r"(?P<usuario>\w+)@(?P<dominio>[\w.]+)", texto)
print(m["usuario"], m["dominio"])
print(re.sub(r"\d", "#", "tel 1234-5678"))
['ana@exemplo.com', 'bia@teste.org']
ana exemplo.com
tel ####-####
enum
Um Enum dá nome a um conjunto fixo de valores e evita as "strings mágicas" espalhadas pelo código:
from enum import Enum, auto
class Status(Enum):
ABERTO = auto()
FECHADO = auto()
print(Status.ABERTO, Status.ABERTO.name, Status["FECHADO"].value)
Status.ABERTO ABERTO 2
Exercício 1
Total por região a partir de um CSV
Escreva total_por_regiao(texto) que receba um CSV com as colunas regiao e valor e devolva um dicionário com a soma de cada região.