Arquivos CSV em Python
Aprenda a ler e escrever arquivos CSV em Python usando o módulo csv integrado, incluindo csv.reader, csv.writer, DictReader e DictWriter com exemplos práticos.
CSV (Comma-Separated Values, ou Valores Separados por Vírgula) é um dos formatos mais comuns para troca de dados tabulares — qualquer aplicativo de planilha, banco de dados e ferramenta de ciência de dados consegue ler e escrever esse formato. O módulo csv integrado ao Python cuida das partes complicadas automaticamente: colocar aspas em campos que contêm vírgulas, eliminar inconsistências de quebra de linha entre sistemas operacionais e mapear linhas para dicionários. Não é necessário instalar nada; o csv já vem em toda instalação Python.
Este capítulo aborda a leitura de arquivos CSV, a escrita de arquivos CSV, o trabalho com DictReader e DictWriter, o uso de delimitadores personalizados e os erros comuns a evitar.
O que é um Arquivo CSV?
Um arquivo CSV é um arquivo de texto simples em que cada linha representa uma linha de dados e cada campo dentro de uma linha é separado por um delimitador — geralmente uma vírgula. Veja um exemplo mínimo:
name,age,city
Alice,30,New York
Bob,25,LondonA primeira linha geralmente é um cabeçalho que dá nome a cada coluna. As linhas seguintes contêm os dados propriamente ditos. Se o valor de um campo contiver uma vírgula, o campo é envolvido em aspas duplas:
name,bio
Alice,"Engineer, New York"O módulo csv trata essas aspas de forma transparente, dispensando a necessidade de fazer o parsing manualmente.
Lendo Arquivos CSV com csv.reader
csv.reader transforma um arquivo aberto (ou qualquer iterável de strings) em um iterador que gera cada linha como uma lista Python.
Padrão básico — ler um arquivo CSV linha por linha
import csv
with open("people.csv", newline="") as f:
reader = csv.reader(f)
for row in reader:
print(row)O argumento newline="" é importante. Sem ele, a tradução universal de quebras de linha do Python pode inserir linhas em branco extras no Windows, pois o módulo csv faz seu próprio tratamento de quebras de linha internamente.
Supondo que people.csv contenha os dados do exemplo acima, a saída é:
['name', 'age', 'city']
['Alice', '30', 'New York']
['Bob', '25', 'London']Observe que todos os valores — incluindo o número 30 — retornam como strings. O módulo csv não infere tipos de dados; converta-os você mesmo quando necessário.
Ignorando a Linha de Cabeçalho
Quando você quer apenas as linhas de dados e não o cabeçalho, chame next() no reader uma vez para consumir a primeira linha:
Ignorar a linha de cabeçalho com next()
import csv
with open("people.csv", newline="") as f:
reader = csv.reader(f)
header = next(reader) # consume and store the header
print("Columns:", header)
for row in reader: # only data rows remain
name, age, city = row
print(f"{name} is {age} years old and lives in {city}.")Saída:
Columns: ['name', 'age', 'city']
Alice is 30 years old and lives in New York.
Bob is 25 years old and lives in London.Carregando Todas as Linhas em uma Lista
Se você precisar do arquivo inteiro na memória de uma vez, passe o reader para list():
import csv
with open("people.csv", newline="") as f:
reader = csv.reader(f)
rows = list(reader)
print(rows[0]) # header row
print(rows[1]) # first data rowSaída:
['name', 'age', 'city']
['Alice', '30', 'New York']Escrevendo Arquivos CSV com csv.writer
csv.writer escreve linhas em qualquer objeto semelhante a um arquivo, colocando aspas automaticamente nos campos que contêm o delimitador, aspas duplas ou caracteres de quebra de linha.
Escrever linhas em um novo arquivo CSV
import csv
rows = [
["product", "price", "quantity"],
["Apple", 1.2, 50],
["Banana", 0.5, 100],
["Cherry", 3.0, 30],
]
with open("inventory.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerows(rows)Após executar isso, inventory.csv contém:
product,price,quantity
Apple,1.2,50
Banana,0.5,100
Cherry,3.0,30Use writer.writerow(row) para escrever uma única linha, ou writer.writerows(rows) para escrever várias de uma vez. Ambos aceitam qualquer iterável.
Por que newline="" é Importante ao Escrever
No Windows, Python abre arquivos de texto em um modo que traduz \n para \r\n. O módulo csv também escreve terminações de linha \r\n por padrão. Juntos, eles produzem \r\r\n — uma linha em branco entre cada linha quando o arquivo é aberto em outro programa. Passar newline="" suprime a tradução extra e deixa o csv gerenciar as terminações de linha por conta própria.
Lendo Arquivos CSV com csv.DictReader
DictReader mapeia cada linha para um OrderedDict (ou dict simples no Python 3.8+) indexado pelos nomes das colunas na linha de cabeçalho. Esta é a abordagem preferida quando as colunas têm nomes significativos e você quer acessá-las pelo nome em vez de pelo índice.
Ler um arquivo CSV como uma sequência de dicionários
import csv
with open("people.csv", newline="") as f:
reader = csv.DictReader(f)
for row in reader:
print(row["name"], "—", row["city"])Saída:
Alice — New York
Bob — LondonDictReader lê automaticamente a primeira linha como cabeçalho. Você pode substituir esse comportamento passando um argumento fieldnames:
import csv
# File has no header; provide field names explicitly
with open("data_no_header.csv", newline="") as f:
reader = csv.DictReader(f, fieldnames=["name", "age", "city"])
for row in reader:
print(row)O atributo reader.fieldnames sempre contém a lista de nomes de colunas em uso, o que é útil para inspeção antes de processar as linhas.
Escrevendo Arquivos CSV com csv.DictWriter
DictWriter é o par correspondente ao DictReader. Você fornece os nomes das colunas com antecedência e, em seguida, escreve dicionários — o writer mapeia cada chave para a coluna correta.
Escrever uma lista de dicionários em um arquivo CSV
import csv
people = [
{"name": "Alice", "age": 30, "city": "New York"},
{"name": "Bob", "age": 25, "city": "London"},
]
fieldnames = ["name", "age", "city"]
with open("people_out.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader() # writes the column-name row
writer.writerows(people)O arquivo resultante:
name,age,city
Alice,30,New York
Bob,25,Londonwriteheader() usa a lista fieldnames fornecida na construção. Chame-o uma vez antes de qualquer chamada a writerow().
Tratando Chaves Extras ou Ausentes
Por padrão, DictWriter lança um ValueError se um dicionário contém uma chave que não está em fieldnames. Você pode alterar esse comportamento com o parâmetro extrasaction:
writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction="ignore")Por outro lado, se um dicionário não tiver uma chave, o writer escreve uma string vazia para aquele campo, a menos que você forneça um padrão em restval:
writer = csv.DictWriter(f, fieldnames=fieldnames, restval="N/A")Delimitadores e Citação Personalizados
Arquivos CSV do mundo real nem sempre são delimitados por vírgulas. Arquivos com valores separados por tabulação (TSV) e arquivos delimitados por pipe são comuns. Use o parâmetro delimiter para lidar com eles:
Ler um arquivo separado por tabulação
import csv
with open("scores.tsv", newline="") as f:
reader = csv.reader(f, delimiter="\t")
for row in reader:
print(row)Escrever um arquivo delimitado por pipe
import csv
with open("output.psv", "w", newline="") as f:
writer = csv.writer(f, delimiter="|")
writer.writerow(["id", "name", "score"])
writer.writerow([1, "Alice", 98])
writer.writerow([2, "Bob", 87])Arquivo de saída:
id|name|score
1|Alice|98
2|Bob|87Constantes de Citação
O parâmetro quoting controla quais campos são colocados entre aspas na saída:
| Constante | Valor | Comportamento |
|---|---|---|
csv.QUOTE_MINIMAL | 0 | Coloca aspas apenas em campos que contêm o delimitador, quotechar ou uma quebra de linha (padrão) |
csv.QUOTE_ALL | 1 | Coloca aspas em todos os campos |
csv.QUOTE_NONNUMERIC | 2 | Coloca aspas em todos os campos não numéricos; o reader converte campos sem aspas para float |
csv.QUOTE_NONE | 3 | Nunca coloca aspas; lança erro se o delimitador aparecer em um campo |
Forçar aspas em todos os campos
import csv, io
output = io.StringIO()
writer = csv.writer(output, quoting=csv.QUOTE_ALL)
writer.writerow(["name", "bio"])
writer.writerow(["Alice", "Engineer, New York"])
print(output.getvalue())Saída:
"name","bio"
"Alice","Engineer, New York"Usando io.StringIO para CSV em Memória
Quando você não precisa acessar o sistema de arquivos — por exemplo, em testes ou ao processar dados CSV recebidos de uma API — use io.StringIO como objeto semelhante a um arquivo:
Analisar CSV a partir de uma string
import csv
import io
raw = "name,score\nAlice,95\nBob,87\n"
reader = csv.DictReader(io.StringIO(raw))
for row in reader:
print(row["name"], "scored", row["score"])Saída:
Alice scored 95
Bob scored 87Erros Comuns
Todos os Valores São Strings
csv.reader e DictReader sempre retornam strings. Converta os valores explicitamente:
age = int(row["age"])
price = float(row["price"])Problemas de Codificação
Abra os arquivos com a codificação correta para evitar UnicodeDecodeError. UTF-8 é a codificação mais comum para arquivos CSV modernos, mas arquivos exportados do Excel podem usar latin-1 ou cp1252:
with open("data.csv", newline="", encoding="utf-8") as f:
reader = csv.reader(f)Linhas em Branco
Se o seu arquivo CSV contiver linhas em branco entre as linhas de dados, csv.reader gera listas vazias [] para elas. Filtre-as:
import csv
with open("data.csv", newline="") as f:
reader = csv.reader(f)
for row in reader:
if not row: # skip blank lines
continue
print(row)Tratamento de Erros
Envolva as operações com arquivos em um bloco try/except para lidar com arquivos ausentes e erros de permissão de forma adequada:
import csv
try:
with open("data.csv", newline="") as f:
reader = csv.reader(f)
for row in reader:
print(row)
except FileNotFoundError:
print("Error: data.csv was not found.")
except PermissionError:
print("Error: no permission to read data.csv.")csv vs Pandas para Arquivos Grandes
O módulo csv é ideal para:
- Arquivos pequenos a médios (até algumas centenas de MB)
- Scripts que não têm o Pandas instalado
- Situações em que você precisa de controle refinado sobre leitura e escrita
Para conjuntos de dados grandes, filtragens complexas ou operações de agregação, a biblioteca de terceiros pandas fornece pd.read_csv() e DataFrame.to_csv(), que são significativamente mais rápidos e ricos em recursos.
Juntando Tudo
O exemplo a seguir lê um arquivo CSV, filtra linhas com base em uma condição e escreve os resultados filtrados em um novo arquivo:
Filtrar linhas e escrever um novo arquivo CSV
import csv
input_file = "inventory.csv"
output_file = "expensive.csv"
with open(input_file, newline="") as infile, \
open(output_file, "w", newline="") as outfile:
reader = csv.DictReader(infile)
writer = csv.DictWriter(outfile, fieldnames=reader.fieldnames)
writer.writeheader()
for row in reader:
if float(row["price"]) >= 1.0:
writer.writerow(row)
print(f"Filtered rows written to {output_file}.")Esse padrão — abrir ambos os arquivos no mesmo bloco with, transmitir linhas do reader para o writer — lida com arquivos de qualquer tamanho sem carregar tudo na memória de uma vez.
Capítulos Relacionados
- Manipulação de Arquivos em Python — abrir, ler e escrever arquivos de texto simples
- Leitura de Arquivos em Python — ler conteúdo de arquivos com
read()ereadlines() - Escrita e Criação de Arquivos em Python — escrever e anexar a arquivos
- Python JSON — trabalhar com JSON, outro formato comum de troca de dados
- Python Try Except — tratar exceções de arquivo não encontrado e outras