Chapter 39, Intermediate
Essential standard library
Before installing a package, check the standard library. These are the modules I use every week.
Code for this chapter: intermediario/cap39_stdlib.py
collections and itertools
The deque with maxlen is the natural structure for "the last N items". The itertools combines and groups iterables without creating intermediate lists:
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
The groupby only groups consecutive equal items, which is why the sorted comes first. Forgetting this is the most common mistake with it.
json
JSON is the data interchange format of the internet. The ensure_ascii=False keeps accents readable, and the indent formats:
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
Notice that True became true and None became null. The Python types that JSON does not recognize (like datetime and Decimal) need to be converted beforehand.
csv
Reading CSV with DictReader gives you dictionaries with the header as the key. The examples use io.StringIO to simulate a file, but with a real file you pass the object of the open() (with 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 and time zones
Store and calculate dates with timezone, preferably in UTC, and convert only when displaying. "Naive" dates (without timezone) are a source of bugs in systems with more than one region:
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
For named timezones and daylight saving time, use zoneinfo.ZoneInfo("America/Sao_Paulo"). On Windows, the timezone database does not come with the system, and you need to install the package tzdata (pip install tzdata).
re
Regular expressions solve extraction and replacement of patterns in text. Use raw strings (r"...") to avoid duplicating backslashes:
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
An Enum names a fixed set of values and avoids "magic strings" scattered throughout the code:
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
Exercise 1
Total by region from a CSV
Write total_por_regiao(texto) that receives a CSV with the columns regiao and valor and returns a dictionary with the sum of each region.