Menu

CSV em Python: ler e escrever arquivos CSV com o módulo csv

Como ler e escrever arquivos CSV em Python — o módulo csv, DictReader e DictWriter, cabeçalhos, aspas e quando recorrer ao pandas.

CSV é mais simples do que parece (e mais complicado do que você esperaria)

Um arquivo CSV é só texto: linhas separadas por quebras de linha, campos separados por vírgulas. Essa é a ideia. Na prática, você esbarra em strings com aspas que contêm vírgulas, campos com quebras de linha embutidas, convenções regionais diferentes (vírgula vs ponto e vírgula), arquivos salvos do Excel que incluem um BOM — casos de borda suficientes para escrever seu próprio line.split(",") ser quase sempre erro.

O módulo embutido csv do Python cuida de tudo. Você raramente vai precisar de outra coisa para arquivos pequenos e médios.

Lendo um CSV com csv.reader

csv.reader produz cada linha como uma lista de strings:

import csv

with open("people.csv", newline="") as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

Alguns detalhes não óbvios:

  • Sempre passe newline="" para open. O módulo csv cuida das quebras de linha; sem isso, você recebe linhas em branco extras no Windows.
  • Todo valor é string. "42" continua sendo string até você chamar int(...) em cima. CSV não tem tipos.
  • A linha de cabeçalho é só mais uma linha. Se seu arquivo tem cabeçalhos, ou pule a primeira linha manualmente ou mude para DictReader.

Pulando a linha de cabeçalho

import csv

with open("people.csv", newline="") as f:
    reader = csv.reader(f)
    headers = next(reader)         # pulls the first row out
    for row in reader:
        print(row)

next(reader) avança o iterador por um e retorna aquela linha.

Lendo como dicts com DictReader

csv.DictReader trata a primeira linha como cabeçalhos e te dá cada linha subsequente como dict:

import csv

with open("people.csv", newline="") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["name"], row["email"])

Isso quase sempre é o que você quer. Nomes de coluna são autodocumentativos, e reordenar colunas no arquivo de origem não quebra seu código.

Se o arquivo não tem cabeçalhos, passe-os explicitamente com fieldnames=["name", "email", ...].

Escrevendo um CSV com csv.writer

csv.writer transforma linhas (listas) em linhas CSV:

import csv

rows = [
    ["name", "age", "city"],
    ["Rosa", 30, "Lisbon"],
    ["Ada", 36, "London"],
]

with open("out.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerows(rows)

writerow(row) escreve uma linha; writerows(rows) escreve um iterável inteiro de uma vez. Os dois colocam aspas em campos automaticamente quando contêm vírgulas, aspas ou quebras de linha — você não precisa pensar nisso.

Escrevendo dicts com DictWriter

Quando seus dados já estão em forma de dict, DictWriter pula o passo "converter para lista":

import csv

people = [
    {"name": "Rosa", "age": 30, "city": "Lisbon"},
    {"name": "Ada", "age": 36, "city": "London"},
]

with open("out.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=["name", "age", "city"])
    writer.writeheader()
    writer.writerows(people)

O argumento fieldnames controla tanto o cabeçalho quanto a ordem das colunas. Chaves nos seus dicts que não estão em fieldnames são silenciosamente descartadas (ou você pode disparar com extrasaction="raise").

Delimitadores e aspas diferentes

Nem todo "CSV" usa vírgulas. Locais europeus muitas vezes usam ;, arquivos separados por tab usam \t, alguns sistemas usam |. Passe um argumento delimiter=:

import csv

with open("data.tsv", newline="") as f:
    reader = csv.reader(f, delimiter="\t")
    for row in reader:
        print(row)

Para arquivos com regras de aspas incomuns, csv.register_dialect(...) permite configurar uma vez e reusar. Para a maioria dos arquivos, os padrões mais delimiter= bastam.

Encoding

Arquivos CSV são texto — têm encoding. UTF-8 é o padrão moderno; arquivos originados do Excel no Windows às vezes usam cp1252 ou incluem um BOM UTF-8. Seja explícito:

with open("data.csv", newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    ...

Se você vê UnicodeDecodeError, o arquivo não é no encoding que você chutou. Tente utf-8-sig (lida com o BOM do Excel), cp1252 ou latin-1 como suspeitos comuns.

Transformando linhas CSV em tipos úteis

Como todo valor chega como string, parsear é com você:

main.py
Output
Click Run to see the output here.

(StringIO deixa a gente rodar o exemplo sem arquivo real — em código de verdade você usaria open(path).)

Para CSVs com tipos complicados (datas, números nullable, true/false com dez grafias diferentes), considere pandas — tem convenções para a maioria já embutidas.

Quando recorrer ao pandas

pandas.read_csv(path) retorna um DataFrame, que é a estrutura certa no momento em que você quer:

  • Filtrar linhas: df[df["active"] == True]
  • Agregar: df.groupby("city")["age"].mean()
  • Juntar com outra tabela
  • Escrever de volta com formatação simples
import pandas as pd

df = pd.read_csv("people.csv")
adults = df[df["age"] >= 18]
adults.to_csv("adults.csv", index=False)

Pandas é exagero para leituras pequenas e lineares — e é uma dependência pesada (pip-install num ambiente virtual). Mas para qualquer coisa com cara de dado, é a ferramenta que a maioria dos analistas Python procura.

Fazendo streaming de arquivos muito grandes

csv.reader já é preguiçoso — lê uma linha de cada vez. Mantenha assim iterando (não chamando list(reader) de antemão), e sua memória fica estável independente do tamanho do arquivo:

import csv

with open("huge.csv", newline="") as f:
    reader = csv.DictReader(f)
    error_count = 0
    for row in reader:
        if row["status"] == "error":
            error_count += 1

print(f"Found {error_count} errors.")

Isso lida com um arquivo de 10 GB tão feliz quanto um de 10 KB, contanto que você não acumule as linhas numa lista.

Alguns hábitos

  • Sempre passe newline="" ao open ao ler ou escrever CSVs.
  • Use DictReader/DictWriter sempre que o arquivo tem cabeçalhos — mais legível do que índices inteiros.
  • Seja explícito sobre encoding, principalmente com arquivos do Excel ou fontes não inglesas.
  • Converta tipos logo no passo da leitura para o código downstream não ter que fazer.
  • Recorra ao pandas quando quiser analisar os dados, não só mover.

Na sequência

Agora você consegue ler JSON e CSV. A última habilidade do mundo real que vamos cobrir é buscar dados pela rede — esse é o próximo doc, sobre requisições HTTP com a biblioteca requests.

Perguntas frequentes

Como leio um arquivo CSV em Python?

Use o módulo embutido csv. csv.reader te dá cada linha como uma lista de strings; csv.DictReader usa a primeira linha como cabeçalhos e produz cada linha como dict. Abra o arquivo com newline='' para o Python não mexer nas quebras de linha: with open('data.csv', newline='') as f:.

Como escrevo um arquivo CSV em Python?

Combine csv.writer com um arquivo aberto em modo escrita e newline=''. Chame writer.writerow([...]) para cada linha ou writer.writerows([[...], [...]]) para um lote. Para dados baseados em dict, use csv.DictWriter — cuida dos cabeçalhos automaticamente.

Devo usar o módulo csv ou pandas?

Use csv para leituras e escritas rápidas, arquivos que você processa linha por linha e quando não quer outra dependência. Use pandas quando precisa filtrar, agrupar ou juntar — ou quando o arquivo é grande o suficiente para operações vetorizadas importarem. Lidam com os mesmos arquivos; a escolha é sobre o que você faz com os dados depois de carregar.

Por que meu CSV tem linhas em branco entre as linhas no Windows?

Você abriu o arquivo sem newline=''. O módulo csv escreve seus próprios terminadores de linha; sem esse argumento, o Python adiciona extras no Windows. Sempre abra arquivos CSV com open(path, newline='') tanto para leitura quanto para escrita.

Aprenda a programar com o Coddy

COMEÇAR