Tabelas como texto
Um arquivo CSV (valores separados por vírgulas) guarda uma tabela como texto: uma linha por registro, células separadas por vírgulas, em geral com uma linha de cabeçalho que nomeia as colunas. Históricos de preços, livros de operações e exportações de quase qualquer ferramenta vêm assim. Parece fácil de ler com line.split(","), mas uma célula pode conter uma vírgula, e então vai entre aspas: AAPL,"Q3, adjusted". Dividir à mão falha nesse caso, então use o módulo padrão csv e abra o arquivo com newline="" para que quebras de linha dentro das células sejam tratadas corretamente.
import csv
# Write a small table with csv.writer
with open("prices.csv", "w", newline="", encoding="utf-8") as file:
writer = csv.writer(file)
writer.writerow(["date", "symbol", "close", "note"])
writer.writerow(["2025-01-02", "AAPL", 184.25, "Q3, adjusted"])
writer.writerow(["2025-01-03", "AAPL", 185.5, ""])
# The comma inside the note is quoted for us
with open("prices.csv", encoding="utf-8") as file:
print(file.read().splitlines()[1]) # 2025-01-02,AAPL,184.25,"Q3, adjusted"Ler linhas
csv.reader(file) produz cada linha como uma lista de strings. csv.DictReader(file) lê primeiro o cabeçalho e depois produz cada linha como um dicionário com os nomes das colunas como chaves, mais legível e imune à troca de ordem das colunas. Em ambos os casos cada célula é texto: converta com float(...) ou int(...) antes de calcular. Passe delimiter=";" (ou "\t") para arquivos com outro separador.
import csv
# DictReader gives each row as a dict; cells are strings
closes = []
with open("prices.csv", newline="", encoding="utf-8") as file:
for row in csv.DictReader(file):
closes.append(float(row["close"]))
print(closes) # [184.25, 185.5]
# csv.reader gives plain lists, header included
with open("prices.csv", newline="", encoding="utf-8") as file:
rows = list(csv.reader(file))
print(rows[0]) # ['date', 'symbol', 'close', 'note']
print(rows[1]) # ['2025-01-02', 'AAPL', '184.25', 'Q3, adjusted']Escrever linhas
csv.writer(file).writerow(values) escreve uma linha e coloca aspas quando necessário; os números são convertidos em texto por você. csv.DictWriter(file, fieldnames=[...]) escreve dicionários, e writeheader() escreve primeiro os nomes das colunas. Abra o arquivo com "w" e newline=""; sem newline="", o Windows pode deixar linhas em branco entre as linhas.
import csv
# DictWriter: header first, then one dict per row
trades = [{"symbol": "AAPL", "quantity": 200}, {"symbol": "MSFT", "quantity": 50}]
with open("trades.csv", "w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=["symbol", "quantity"])
writer.writeheader()
writer.writerows(trades)
with open("trades.csv", encoding="utf-8") as file:
print(file.read().splitlines()) # ['symbol,quantity', 'AAPL,200', 'MSFT,50']import csv
# Cells are text until you convert them
with open("prices.csv", newline="", encoding="utf-8") as file:
row = next(csv.DictReader(file))
print(repr(row["close"]), row["close"] * 2) # '184.25' 184.25184.25
print(float(row["close"]) * 2) # 368.5
# Another separator: semicolons
with open("euro.csv", "w", newline="", encoding="utf-8") as file:
csv.writer(file, delimiter=";").writerow(["AAPL", "184,25"])
with open("euro.csv", newline="", encoding="utf-8") as file:
print(next(csv.reader(file, delimiter=";"))) # ['AAPL', '184,25']184.25, 200 e AAPL são só caracteres até você convertê-los. Esquecer isso dá "184.25" * 200 (o texto repetido 200 vezes) em vez de um erro. Converta cada coluna uma vez, onde a lê, e confira os nomes do cabeçalho em vez de supor posições.- Abra com
newline=""; não divida nem junte linhas CSV à mão. csv.DictReaderlê linhas como dicionários; cada célula é uma string.csv.writer/csv.DictWriterescrevem linhas e colocam as aspas por você.
A seguir: dados JSON, para registros aninhados que não cabem numa tabela plana.
Lab: o que é avaliado
- Agrupar os fechamentos por símbolo com
read_closes25 pts - Salvar operações como CSV com
write_trades25 pts - Totalizar o valor negociado por símbolo com
total_by_symbol25 pts - Copiar as linhas de um símbolo para um novo arquivo com
filter_rows25 pts