© E.L.
Favero Algoritmos em Python 128
Capítulo
19 ARQUIVOS NO PYTHON
Apresentamos arquivos de dados numéricos, arquivos de texto e arquivos tipo csv.
Mostramos como quebrar string de textos em linhas e linhas em colunas de dados. Como ler
e escrever nestes tipos de arquivos.
19.1 Arquivos no Python
Um arquivo deve ser aberto e fechado, com open() e close(). Por exemplo, abrir um arquivo
arq1.txt e escrever uma linha no arquivo aberto.
arq=open('arq1.txt', 'w')
arq.write('uma linha do arquivo')
arq.close ()
Um arquivo precisa ser aberto e fechado. Uma forma de fazer isto sem se esquecer de
fechar é usando o with que já abre e fecha o arquivo. Tudo que é executado dentro do boco
with é feito com o arquivo aberto. Fora do bloco o arquivo está fechado. Neste caso o with
abstrai os comandos de abre e fecha.
with open('arq1.txt', 'w') as arq:
arq.write('uma linha do arquivo\n')
arq.write('uma 2da linha do arquivo')
print('aqui o arquivo já está fechado')
Nos parâmetros de abertura temos várias opções, w, w+, wb, wb+, r, a+, etc. conforme a
tabela abaixo:
Argumento Ação
W Cria um novo arquivo para escrita.
w+ O mesmo que “w”, mas abre para escrita e leitura.
R Abre para leitura.
A Abre para escrita, adicionando conteúdos novos no final.
a+ Idem ‘a’, mas abre para leitura e escrita.
B Idem com os modos descritos, mas para arquivos binários (wb, rb, ab+,...).
Para leitura do arquivo usa-se read(); podemos informar quantos caracteres ler; se não
colocamos nada ele lê tudo.
© E.L.Favero Algoritmos em Python 129
arq = open('meuarquivo.txt') # r é default
leitura = arq.read(3)
print(leitura)
restante=arq.read()
print(restante)
arq.close ()
19.2 Trabalhando com dados numéricos
Um arquivo é uma lista de linhas e/ou registros. Se for de texto é uma lista de linhas. Senão
é uma lista de registros. O comando arq.write() equivale ao comando print(), porém a escrita
ocorre no arquivo aberto como “w” (write).
import random
arquivo = open("números.txt","w")
for linha in range(1,11):
x=random.randint(1000,10000)
arquivo.write("%d %d \n" % (linha, x))
arquivo.close()
print('veja resultado em números.txt')
>>>
1 5774
2 8701
3 2562
4 2951
5 7279
…
10 5186
#Idem anterior porém com duas colunas de números gerados
import random
arquivo = open("números1.csv","w")
for linha in range(1,11 ):
x=random.randint(1000,10000)
y=random.randint(1000,10000)
arquivo.write("%d, %d, %d \n" % (linha, x,y))
arquivo.close()
print('veja resultado em números1.csv')
19.3 Pensamento computacional: interpretador x compilador
Vamos trabalhar “mais menos”. Suar menos fazendo mais. Programar numa linguagem
compilada (como C ou Java) é mais difícil que trabalhar numa linguagem interpretada como
Python. O tempo de espera entre dois ciclos de interação (edita, compila, roda) é maior
numa linguagem compilada. Um interpretador permite diminuir o tempo de espera entre os
ciclos de interação (edita, checa, roda). O interpretador também permite testar comandos
imediatamente no shell. Numa linguagem compilada, às vezes leva um tempo para saber o
retorno de um determinado comando. O compilador também tem suas vantagens: em
muitos programas o tempo de um código compilado é 10 vezes menor. Se o objetivo é
desempenho do algoritmo o compilador é melhor. Se o objetivo e praticar a codificação de
algoritmos o interpretador é melhor.
Um pensamento computacional similar ocorre quando programamos com arquivos.
Podemos fazer tudo na memória sem ficar abrindo e fechando arquivos. Pois se
trabalhamos nos arquivos temos que ficar abrindo os arquivos num editor de texto para ver o
© E.L.Favero Algoritmos em Python 130
que aconteceu com a saída do programa gerada dentro arquivo. Vamos aqui ilustar o jeito
Python.
Vamos trabalhar com os dados gerados pelo código acima, as três colunas de
números respectivamente (nro da linha, aleatório 1, aleatório 2). Abrindo o arquivo e
copiando o conteúdo para dentro de uma string com três aspas, dentro do código do
programa.
LINHAS é a string, quebrada em linhas – split('\n'); desprezamos a primeira e
última linha pois são vazias – [1:-1] pega-se a fatia sem a primeira e a última. Agora
podemos ver LINHAS como uma lista de linhas; um arquivo texto é uma lista de linhas.
Vamos pegar cada linha de LINHAS e quebrar na vírgula split(','); depois da quebra temos
três campos tipo string a[0], a[1], a[2]; desprezando o número da linha vamos usar só a[1] e
a[2]. Transformamos eles para valores inteiros para calcular a média.
LINHAS='''
1, 9808, 8761
2, 8833, 4791
3, 9868, 9938
4, 3033, 9231
5, 3830, 7532
'''.split('\n')[1:-1]
for linha in LINHAS:
a=linha.split(',')
x=int(a[1])
y=int(a[2])
media=round((x+y)/2, 2)
print(a, media)
>>>
['1', ' 9808', ' 8761 '] 9284.5
['2', ' 8833', ' 4791 '] 6812.0
['3', ' 9868', ' 9938 '] 9903.0
['4', ' 3033', ' 9231 '] 6132.0
['5', ' 3830', ' 7532 '] 5681.0
Agora vamos repetir o procedimento acima, porém trabalhando diretamento com o arquivo,
ler um arquivo e escrever um novo arquivo com a média dos dois valores para cada linha.
Veja acima como criar o arquivo números1.csv.
arquivo = open("números1.csv","r")
arquivo2= open("números2.csv","w")
LINHAS=arquivo.readlines()
for linha in LINHAS:
a=linha.split(',')
x=int(a[1])
y=int(a[2])
media=round((x+y)/2, 2)
print(a, media)
arquivo2.write("%s, %d, %d, %0.2f \n" % (a[0], x,y, media))
arquivo.close()
arquivo2.close()
print('veja resultado em números2.csv')
'''
0, 9808, 8761, 9284.50
1, 8833, 4791, 6812.00
© E.L.Favero Algoritmos em Python 131
2, 9868, 9938, 9903.00
3, 3033, 9231, 6132.00
...
'''
Projeto. Leia o arquivo com duas colunas e calcule a soma de cada coluna. Calcule
também a média, mínimo e máximo de cada coluna.
Projeto. Leia o arquivo com 3 colunas e 3 linhas. Acrescente uma coluna com a soma das
linhas. Acrescente uma linha com a soma de cada coluna, inclusive a nova das somas,
ficando assim:
[2, 3, 8] [2, 3, 8, 13]
[12, 1, 19] => [12, 1, 19, 32]
[3, 27, 2] [3, 27, 2, 32]
[17, 31, 29,77]
19.4 Arquivos tipo CSV
Um arquivo com extensão csv (comma-separated values) é visto como uma lista de linhas
onde cada linha também é uma lista de valores. No arquivo físico as linhas são registradas
como texto, onde os valores são separados por vírgulas.
5.1, 3.5, 1.4, 0.2, 'virginica'
4.9, 3.0, 1.4, 0.2, 'setosa'
4.7, 3.2, 1.3, 0.2, 'versicolor'
4.6, 3.1, 1.5, 0.2, 'setosa'
5.4, 3.9, 1.7, 0.4, 'setosa'
Quando o Python lê o arquivo através da biblioteca csv o arquivo é lido como uma lista de
linhas. Onde cada linha é uma lista de campos do tipo string. Neste exemplo, as 4 primeiras
colunas são numéricas, então precisamos converte-las para float. Vamos definir a função
x2Num() que converte um valor para um valor float ou retorna o string caso não seja um
valor numérico.
from csv import reader
def x2Num(x):
try:
return float(x)
except ValueError:
return x
print( x2Num('102'), x2Num('102.85'), x2Num('a102'), x2Num('abc'))
print( list(map(x2Num, ['102', '102.85', 'abc'])))
print( [ x2Num(x) for x in ['102', '102.85', 'abc']])
>>>
'''
102.0 102.85 a102 abc
[102.0, 102.85, 'abc']
[102.0, 102.85, 'abc']
'''
O comando try/except é similar a um if/else mas foi criado para tratar exceções. Se um
comando dentro do try falha o Python se recupera ativando a exceção, que pode executar
uma estratégia alternativa que não falhe, como neste caso.
19.5 Arquivo como matriz
Pensamento computacional: como manipular o arquivo como uma matriz. Por exemplo, é
fácil calcular a média de cada coluna da tabela, matriz do arquivo. Segue abaixo um
exemplo, onde queremos calcular a média e o mínimo da coluna 1 e 3. Vamos usar o
© E.L.Favero Algoritmos em Python 132
comando list(zip(*)) para transladar a matriz, onde as colunas viram linhas e vice versa.
Assim temos duas representações arq e arqX, facilitando o processamento das linhas e/ou
colunas. Note que list(zip(*)) não devolve uma lista de lista, mas sim uma lista de tuplas.
Porém para efeito de calcular a média, tuplas ou listas são similares.
arq=[
[5.1, 3.5, 1.4, 0.2, 'virginica'],
[4.9, 3.0, 1.4, 0.2, 'setosa'],
[4.7, 3.2, 1.3, 0.2, 'versicolor'],
[4.6, 3.1, 1.5, 0.2, 'setosa'],
[5.4, 3.9, 1.7, 0.4, 'setosa'],
[5.0, 3.6, 1.4, 0.2, 'versicolor'],
[4.6, 3.4, 1.4, 0.3, 'virginica'],
[5.0, 3.4, 1.5, 0.2, 'setosa'],
[4.4, 2.9, 1.4, 0.2, 'virginica']]
arqX=list(zip(* arq))
print(arqX)
>>>
'''
[(5.1, 4.9, 4.7, 4.6, 5.4, 5.0, 4.6, 5.0, 4.4),
(3.5, 3.0, 3.2, 3.1, 3.9, 3.6, 3.4, 3.4, 2.9),
(1.4, 1.4, 1.3, 1.5, 1.7, 1.4, 1.4, 1.5, 1.4),
(0.2, 0.2, 0.2, 0.2, 0.4, 0.2, 0.3, 0.2, 0.2),
('virginica', 'setosa', 'versicolor', 'setosa',..., 'virginica')]
'''
def med(c): return round(sum(c)/len(c),2)
print( '1ra col: media=', med(arqX[0]), 'min=', min(arqX[0]))
print( '3ra col: media=', med(arqX[2]), 'min=', min(arqX[2]))
>>>
'''
1ra col: media= 4.86 min= 4.4
3ra col: media= 1.44 min= 1.3
'''
19.6 Carregar um arquivo CSV e calcular a média das colunas
Vamos carregar um arquivo csv dentro de uma variável ARQ, que é uma lista de linhas não
nulas. Com a função x2Num() vamos converter cada valor numérico no seu valor
correspondente: [x2Num(x) for x in lin]. Depois de carregar escrevemos quantas linhas e
quantas colunas tem o arquivo. Com o comando ARQ=ARQ[1:] eliminamos a linha de
cabeçalho. E com arqX= list(zip(* ARQ)) criamos outra versão do arquivo onde cada linha se
transforma numa coluna. Nesta versão podemos calcular as médias e mínimos de cada
coluna.
Na parte final do arquivo imprimos as 10 linhas com as menores somas. Para isso
cria-se uma lista LIN com as tuplas (linha, soma); a soma pega apenas os 4 campos de
valores de cada linha i, sum(ARQ[i][:-1]). A fatia [:-1] ignora o campo da classe, a última
coluna. Para ordenar sobre o valor da soma usamos LIN.sort(key=lambda x: x[1]).
from csv import reader
def x2Num(x):
try:return float(x)
except ValueError: return x
def med(c): return round(sum(c)/len(c),2)
def load_csv(arqnome):
ARQ = list()
© E.L.Favero Algoritmos em Python 133
with open(arqnome, 'r') as arq:
linhas = reader(arq)
for lin in linhas:
if not lin:continue
ARQ.append( [x2Num(x) for x in lin] )
return ARQ
ARQ = load_csv('iris.csv')
print('carregou:',len(ARQ), 'linhas cada com', len(ARQ[0]), 'colunas')
print('cabeçalho:',ARQ[0])
ARQ=ARQ[1:] # tira o cabeçalho
arqX= list(zip(* ARQ))
print('ex linhas :',ARQ[0:5])
print('coluna 1 [:10]:', arqX[0][:10])
print( '1ra col: media=', med(arqX[0]), 'min=', min(arqX[0]))
print( '2da col: media=', med(arqX[1]), 'min=', min(arqX[1]))
print( '3ra col: media=', med(arqX[2]), 'min=', min(arqX[2]))
print( '4ta col: media=', med(arqX[3]), 'min=', min(arqX[3]))
print('10 linhas com menor somas')
LIN=[]
for i in range(1,len(ARQ)):
LIN.append( (i, round( sum(ARQ[i][:-1]),2) ))
LIN.sort(key=lambda x: x[1])
print(LIN[:10])
>>>
'''
carregou: 151 linhas cada com 5 colunas
cabeçalho: ['sepal_length', 'sepal_width', 'petal_length',
'petal_width', 'species']
ex linhas : [[5.1, 3.5, 1.4, 0.2, 'setosa'],
[4.9, 3.0, 1.4, 0.2, 'setosa'], [4.7, 3.2, 1.3, 0.2, 'setosa'],
[4.6, 3.1, 1.5, 0.2, 'setosa'], [5.0, 3.6, 1.4, 0.2, 'setosa']]
coluna 1 [:10]: (5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4.9)
1ra col: media= 5.84 min= 4.3
2da col: media= 3.05 min= 2.0
3ra col: media= 3.76 min= 1.0
4ta col: media= 1.2 min= 0.1
10 linhas com menor somas:
[(41, 8.4), (13, 8.5), (8, 8.9), (38, 8.9), (42, 9.1), (12, 9.3),
(2, 9.4), (3, 9.4), (22, 9.4), (47, 9.4)]
Projeto. Ler o arquivo íris.csv e imprimir o min, max, média e o desvio padrão de cada
coluna.
19.6.1 Perguntas conceituais
Responda com no mínimo 10 palavras e no máximo 20 palavras:
C19.1 O que é um arquivo. Como um arquivo é visto em Python?
© E.L.Favero Algoritmos em Python 134
Responda com no mínimo 30 palavras e máximo 50 palavras
C19.2 Qual a vantagem de se trabalhar com um interpretador de comandos?