Como ler um arquivo linha por linha em uma lista?

2027

Como leio todas as linhas de um arquivo no Python e armazeno cada linha como um elemento em uma lista?

Quero ler o arquivo linha por linha e anexar cada linha ao final da lista.

Julie Raswick
fonte

Respostas:

2174
with open(filename) as f:
    content = f.readlines()
# you may also want to remove whitespace characters like `\n` at the end of each line
content = [x.strip() for x in content] 
SilentGhost
fonte
206
Não use file.readlines()em um forloop, um objeto de arquivo em si é suficiente:lines = [line.rstrip('\n') for line in file]
jfs
88
No caso de você estar trabalhando com Big Data, o uso readlines()não é muito eficiente, pois pode resultar em MemoryError . Nesse caso, é melhor iterar sobre o arquivo usando for line in f:e trabalhando com cada linevariável.
precisa saber é o seguinte
7
Eu verifiquei o perfil da memória de diferentes maneiras, dadas nas respostas, usando o procedimento mencionado aqui . O uso da memória é muito melhor quando cada linha é lida no arquivo e processada, conforme sugerido por @DevShark aqui . Manter todas as linhas em um objeto de coleção não é uma boa ideia se a memória for uma restrição ou se o arquivo for grande. O tempo de execução é semelhante nas duas abordagens.
precisa
6
Além disso, .rstrip()funcionará um pouco mais rápido se você estiver removendo os espaços em branco do final das linhas.
Gringo Suave
Oneliner:with open(filename) as f: content = [i.strip() for i in f.readlines()]
Vishal Gupta
1002

Consulte Entrada e Saída :

with open('filename') as f:
    lines = f.readlines()

ou com a remoção do caractere de nova linha:

with open('filename') as f:
    lines = [line.rstrip() for line in f]
Felix Kling
fonte
12
Melhor, uso f.read().splitlines(), que faz novas linhas remove
Mark
A segunda versão é for line in open(filename)segura? Ou seja, o arquivo será fechado automaticamente?
Becko
2
É melhor ler o arquivo uma linha de cada vez, em vez de ler o arquivo inteiro na memória de uma só vez. Fazer isso não se adapta bem a arquivos de entrada grandes. Veja abaixo a resposta de robert.
Brad Hein
1
lines = [x.rstrip('\n') for x in open('data\hsf.txt','r')]Se eu escrever dessa maneira, como posso fechar o arquivo após a leitura?
Ramisa Anjum Aditi
2
Sim, a ponto de outras pessoas estarem aqui, embora não seja uma "prática recomendada" usar opensem o gerenciador de contexto (ou alguma outra maneira garantida de fechá-lo), esse não é realmente um desses casos - quando o objeto não tem mais referências para ele será coletado o lixo e o arquivo será fechado, o que deve ocorrer imediatamente com erro ou não, quando a compreensão da lista for concluída.
Aaron Hall
579

Isso é mais explícito do que o necessário, mas faz o que você deseja.

with open("file.txt") as file_in:
    lines = []
    for line in file_in:
        lines.append(line)
Robert
fonte
18
Prefiro essa resposta, pois ela não requer o carregamento do arquivo inteiro na memória (nesse caso, ele ainda está anexado array, mas pode haver outras circunstâncias). Certamente para arquivos grandes, essa abordagem pode atenuar problemas.
JohannesB
1
Anexar a uma matriz é lento. Não consigo pensar em um caso de uso em que essa seja a melhor solução.
Elias Strehle 04/10/19
@haccks é melhor porque não carrega o arquivo inteiro na memória ou existe mais?
precisa saber é o seguinte
4
Nota: Esta solução não retira novas linhas.
AMC
1
Esta solução carrega o arquivo inteiro na memória. Não sei por que as pessoas pensam que não.
andrebrait
274

Isso produzirá uma "matriz" de linhas do arquivo.

lines = tuple(open(filename, 'r'))

openretorna um arquivo que pode ser iterado. Quando você itera sobre um arquivo, obtém as linhas desse arquivo. tuplepode usar um iterador e instanciar uma instância de tupla para você a partir do iterador fornecido. linesé uma tupla criada a partir das linhas do arquivo.

Noctis Skytower
fonte
31
@MarshallFarrier Tente em lines = open(filename).read().split('\n')vez disso.
Noctis Skytower
16
fecha o arquivo?
Vanuan
5
@Vanuan Como não há referência remanescente ao arquivo após a execução da linha, o destruidor deve fechar o arquivo automaticamente.
Noctis Skytower
30
@NoctisSkytower Acho lines = open(filename).read().splitlines()um pouco mais limpo e acredito que ele também lida melhor com as terminações de linha do DOS.
Jaynp 13/05
8
@ mklement0 Supondo um arquivo de 1000 linhas, um listocupa cerca de 13,22% mais espaço que um tuple. Os resultados vêm from sys import getsizeof as g; i = [None] * 1000; round((g(list(i)) / g(tuple(i)) - 1) * 100, 2). Criar um tupleleva cerca de 4,17% mais tempo do que criar um list(com um desvio padrão de 0,16%). Os resultados vêm da execução from timeit import timeit as t; round((t('tuple(i)', 'i = [None] * 1000') / t('list(i)', 'i = [None] * 1000') - 1) * 100, 2)30 vezes. Minha solução favorece o espaço sobre a velocidade quando a necessidade de mutabilidade é desconhecida.
Noctis Skytower
194

Se você deseja \nincluir:

with open(fname) as f:
    content = f.readlines()

Se você não deseja \nincluir:

with open(fname) as f:
    content = f.read().splitlines()
Eneko Alonso
fonte
168

De acordo com os Métodos de objetos de arquivo do Python , a maneira mais simples de converter um arquivo de texto em um listé:

with open('file.txt') as f:
    my_list = list(f)

Se você apenas precisar percorrer as linhas do arquivo de texto, poderá usar:

with open('file.txt') as f:
    for line in f:
       ...

Resposta antiga:

Usando withe readlines():

with open('file.txt') as f:
    lines = f.readlines()

Se você não se importa em fechar o arquivo, esta linha única funciona:

lines = open('file.txt').readlines()

A maneira tradicional :

f = open('file.txt') # Open file on read mode
lines = f.read().split("\n") # Create a list containing all lines
f.close() # Close file
CONvid19
fonte
150

Você pode simplesmente fazer o seguinte, como foi sugerido:

with open('/your/path/file') as f:
    my_lines = f.readlines()

Observe que essa abordagem tem duas desvantagens:

1) Você armazena todas as linhas na memória. No caso geral, essa é uma péssima idéia. O arquivo pode ser muito grande e você pode ficar sem memória. Mesmo que não seja grande, é simplesmente um desperdício de memória.

2) Isso não permite o processamento de cada linha enquanto você as lê. Portanto, se você processar suas linhas depois disso, não será eficiente (requer duas passagens em vez de uma).

Uma abordagem melhor para o caso geral seria a seguinte:

with open('/your/path/file') as f:
    for line in f:
        process(line)

Onde você define sua função do processo da maneira que desejar. Por exemplo:

def process(line):
    if 'save the world' in line.lower():
         superman.save_the_world()

(A implementação da Supermanclasse é deixada como um exercício para você).

Isso funcionará bem para qualquer tamanho de arquivo e você o analisará em apenas 1 passagem. Normalmente, é assim que os analisadores genéricos funcionam.

DevShark
fonte
5
Era exatamente disso que eu precisava - e obrigado por explicar as desvantagens. Como iniciante em Python, é incrível entender por que uma solução é a solução. Felicidades!
Ephexx 17/05
5
Pense um pouco mais, Corey. Você realmente quer que seu computador leia cada linha, sem fazer nada com essas linhas? Certamente você pode perceber que sempre precisa processá-los de uma maneira ou de outra.
DevShark
5
Você sempre precisa fazer algo com as linhas. Pode ser tão simples quanto imprimir as linhas ou contá-las. Não há valor em fazer com que seu processo leia as linhas na memória, mas não faça nada com ele.
DevShark
2
Você sempre precisa fazer algo com eles. Acho que o que você está tentando enfatizar é que você pode aplicar uma função a todos eles de uma só vez, em vez de um por um. Esse é realmente o caso algumas vezes. Mas, do ponto de vista da memória, é muito ineficiente e impede a leitura de arquivos se o espaço ocupado for maior que o seu RAM. É por isso que os analisadores tipicamente genéricos operam da maneira que descrevi.
DevShark
2
@PierreOcinom está correto. Como o arquivo é aberto no modo somente leitura, você não pode modificar o arquivo original com o código acima. Para abrir um arquivo para leitura e escrita, o usoopen('file_path', 'r+')
DevShark
66

Dados na lista

Suponha que tenhamos um arquivo de texto com nossos dados, como nas linhas a seguir,

Conteúdo do arquivo de texto:

line 1
line 2
line 3
  • Abra o cmd no mesmo diretório (clique com o botão direito do mouse e escolha cmd ou PowerShell)
  • Execute pythone, no intérprete, escreva:

O script Python:

>>> with open("myfile.txt", encoding="utf-8") as file:
...     x = [l.rstrip("\n") for l in file]
>>> x
['line 1','line 2','line 3']

Usando anexar:

x = []
with open("myfile.txt") as file:
    for l in file:
        x.append(l.strip())

Ou:

>>> x = open("myfile.txt").read().splitlines()
>>> x
['line 1', 'line 2', 'line 3']

Ou:

>>> x = open("myfile.txt").readlines()
>>> x
['linea 1\n', 'line 2\n', 'line 3\n']

Ou:

def print_output(lines_in_textfile):
    print("lines_in_textfile =", lines_in_textfile)

y = [x.rstrip() for x in open("001.txt")]
print_output(y)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = file.read().splitlines()
    print_output(file)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = [x.rstrip("\n") for x in file]
    print_output(file)

resultado:

lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']
Giovanni G. PY
fonte
1
read().splitlines()é fornecido pelo Python: é simples readlines()(o que provavelmente é mais rápido, pois é menos dispendioso).
Eric O Lebigot
1
@EricOLebigot a partir dos exemplos mostrados, parece read().splitlines()e readlines()não produz a mesma saída. Tem certeza de que eles são equivalentes?
craq
1
Se você usar apenas linhas de leitura, precisará usar o método strip para se livrar do \ n no texto, então mudei os últimos exemplos usando uma compreensão de lista para ter a mesma saída nos dois casos. Portanto, se você usar read (). Readlines (), terá um item "limpo" com a linha e sem o caractere de nova linha; caso contrário, deverá fazer o que vê no código acima.
Giovanni G. PY
1
De fato. Note que no código acima todo o strip()deve ser rstrip("\n")ou espaços em torno de uma linha são excluídos. Além disso, não há sentido em fazer readlines()uma compreensão de lista: simplesmente iterar sobre o arquivo é melhor, pois não desperdiça tempo e memória criando uma lista intermediária das linhas.
Eric O Lebigot
1
@EricOLebigot Concluído, obrigado.
Giovanni G. PY
43

Para ler um arquivo em uma lista, você precisa fazer três coisas:

  • Abra o arquivo
  • Leia o arquivo
  • Armazene o conteúdo como lista

Felizmente, o Python torna muito fácil fazer essas coisas; portanto, a maneira mais curta de ler um arquivo em uma lista é:

lst = list(open(filename))

No entanto, vou adicionar mais algumas explicações.

Abrindo o arquivo

Presumo que você deseja abrir um arquivo específico e não lida diretamente com um identificador de arquivo (ou um identificador de arquivo). A função mais usada para abrir um arquivo no Python é o seguinte open: é necessário um argumento obrigatório e dois opcionais no Python 2.7:

  • Nome do arquivo
  • Modo
  • Buffer (ignorarei esse argumento nesta resposta)

O nome do arquivo deve ser uma sequência que representa o caminho para o arquivo . Por exemplo:

open('afile')   # opens the file named afile in the current working directory
open('adir/afile')            # relative path (relative to the current working directory)
open('C:/users/aname/afile')  # absolute path (windows)
open('/usr/local/afile')      # absolute path (linux)

Observe que a extensão do arquivo precisa ser especificada. Isso é especialmente importante para usuários do Windows, porque extensões de arquivo como .txtou .docetc. estão ocultas por padrão. quando exibidas no explorer.

O segundo argumento é o mode, é rpor padrão o que significa "somente leitura". É exatamente isso que você precisa no seu caso.

Mas caso você realmente queira criar um arquivo e / ou gravar em um arquivo, precisará de um argumento diferente aqui. Existe uma excelente resposta se você quiser uma visão geral .

Para ler um arquivo, você pode omitir modeou passá-lo explicitamente:

open(filename)
open(filename, 'r')

Ambos abrirão o arquivo no modo somente leitura. Caso você queira ler um arquivo binário no Windows, use o modo rb:

open(filename, 'rb')

Em outras plataformas, o 'b'(modo binário) é simplesmente ignorado.


Agora que mostrei como openo arquivo, vamos falar sobre o fato de que você sempre precisa closenovamente. Caso contrário, ele manterá um identificador de arquivo aberto até que o processo termine (ou o Python retarda o identificador de arquivo).

Enquanto você pode usar:

f = open(filename)
# ... do stuff with f
f.close()

Isso falhará ao fechar o arquivo quando algo entre opene closelança uma exceção. Você pode evitar isso usando um trye finally:

f = open(filename)
# nothing in between!
try:
    # do stuff with f
finally:
    f.close()

No entanto, o Python fornece gerenciadores de contexto com uma sintaxe mais bonita (mas opené quase idêntica à trye finallyacima):

with open(filename) as f:
    # do stuff with f
# The file is always closed after the with-scope ends.

A última abordagem é a abordagem recomendada para abrir um arquivo no Python!

Lendo o arquivo

Ok, você abriu o arquivo, agora como lê-lo?

A openfunção retorna um fileobjeto e suporta o protocolo de iteração Pythons. Cada iteração fornecerá uma linha:

with open(filename) as f:
    for line in f:
        print(line)

Isso imprimirá cada linha do arquivo. Observe, no entanto, que cada linha conterá um caractere de nova linha \nno final (você pode verificar se o seu Python é construído com suporte universal a novas linhas - caso contrário, você também pode ter \r\nno Windows ou \rno Mac como novas linhas). Se você não quiser, pode simplesmente remover o último caractere (ou os dois últimos caracteres no Windows):

with open(filename) as f:
    for line in f:
        print(line[:-1])

Mas a última linha não tem necessariamente uma nova linha à direita, portanto, não se deve usá-la. Pode-se verificar se termina com uma nova linha à direita e, em caso afirmativo, removê-la:

with open(filename) as f:
    for line in f:
        if line.endswith('\n'):
            line = line[:-1]
        print(line)

Mas você pode simplesmente remover todos os espaços em branco (incluindo o \ncaractere) do final da string , isso também removerá todos os outros espaços em branco à direita, para que você tenha cuidado se estes forem importantes:

with open(filename) as f:
    for line in f:
        print(f.rstrip())

No entanto, se as linhas terminarem com \r\n(Windows "newlines"), isso .rstrip()também cuidará do \r!

Armazene o conteúdo como lista

Agora que você sabe como abrir o arquivo e lê-lo, é hora de armazenar o conteúdo em uma lista. A opção mais simples seria usar a listfunção:

with open(filename) as f:
    lst = list(f)

Caso deseje remover as novas linhas à direita, use uma compreensão da lista:

with open(filename) as f:
    lst = [line.rstrip() for line in f]

Ou ainda mais simples: o .readlines()método do fileobjeto, por padrão, retorna uma listdas linhas:

with open(filename) as f:
    lst = f.readlines()

Isso também inclui os caracteres de nova linha à direita. Se você não os quiser, eu recomendaria o [line.rstrip() for line in f] abordagem, pois evita manter duas listas contendo todas as linhas na memória.

Há uma opção adicional para obter a saída desejada, porém é "subótima": reado arquivo completo em uma string e depois dividido em novas linhas:

with open(filename) as f:
    lst = f.read().split('\n')

ou:

with open(filename) as f:
    lst = f.read().splitlines()

Eles cuidam das novas linhas à direita automaticamente porque o split personagem não está incluído. No entanto, eles não são ideais porque você mantém o arquivo como string e como uma lista de linhas na memória!

Sumário

  • Use with open(...) as fao abrir arquivos porque você não precisa fechar o arquivo sozinho e ele fecha o arquivo mesmo que ocorra alguma exceção.
  • file objetos suportam o protocolo de iteração, portanto, ler um arquivo linha por linha é tão simples quanto for line in the_file_object: .
  • Sempre procure na documentação as funções / classes disponíveis. Na maioria das vezes, há uma combinação perfeita para a tarefa ou pelo menos uma ou duas boas. A escolha óbvia nesse caso seria, readlines()mas se você quiser processar as linhas antes de armazená-las na lista, eu recomendaria uma compreensão simples da lista.
MSeifert
fonte
A última abordagem é a abordagem recomendada para abrir um arquivo no Python! Por que é a última, então? A grande maioria das pessoas não olha apenas para as primeiras linhas de resposta antes de seguir em frente?
AMC
@ AMC Não pensei muito nisso quando escrevi a resposta. Você acha que eu deveria colocá-lo no topo da resposta?
MSeifert 9/01
Pode ser melhor, sim. Também notei que você mencionou o Python 2, para que também pudesse ser atualizado.
AMC
Ah, a pergunta foi originalmente marcada como python-2.x. Pode fazer sentido atualizá-lo de maneira mais geral. Vou ver se chego a isso na próxima vez. Obrigado por suas sugestões. Muito apreciado!
MSeifert 9/01
42

Maneira limpa e pitônica de ler as linhas de um arquivo em uma lista


Em primeiro lugar, você deve se concentrar em abrir seu arquivo e ler seu conteúdo de maneira eficiente e pitônica. Aqui está um exemplo da maneira que eu pessoalmente NÃO prefiro:

infile = open('my_file.txt', 'r')  # Open the file for reading.

data = infile.read()  # Read the contents of the file.

infile.close()  # Close the file since we're done using it.

Em vez disso, prefiro o método abaixo de abrir arquivos para leitura e gravação, pois é muito limpo e não requer uma etapa extra para fechar o arquivo quando você terminar de usá-lo. Na declaração abaixo, estamos abrindo o arquivo para leitura e atribuindo-o à variável 'infile'. Depois que o código nesta instrução terminar a execução, o arquivo será fechado automaticamente.

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

Agora, precisamos nos concentrar em trazer esses dados para uma lista Python, porque eles são iteráveis, eficientes e flexíveis. No seu caso, o objetivo desejado é trazer cada linha do arquivo de texto para um elemento separado. Para fazer isso, usaremos o método splitlines () da seguinte maneira:

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

O produto final:

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

Testando nosso código:

  • Conteúdo do arquivo de texto:
     A fost odatã ca-n povesti,
     A fost ca niciodatã,
     Din rude mãri împãrãtesti,
     O prea frumoasã fatã.
  • Imprima instruções para fins de teste:
    print my_list  # Print the list.

    # Print each line in the list.
    for line in my_list:
        print line

    # Print the fourth element in this list.
    print my_list[3]
  • Saída (aparência diferente devido a caracteres unicode):
     ['A fost odat\xc3\xa3 ca-n povesti,', 'A fost ca niciodat\xc3\xa3,',
     'Din rude m\xc3\xa3ri \xc3\xaemp\xc3\xa3r\xc3\xa3testi,', 'O prea
     frumoas\xc3\xa3 fat\xc3\xa3.']

     A fost odatã ca-n povesti, A fost ca niciodatã, Din rude mãri
     împãrãtesti, O prea frumoasã fatã.

     O prea frumoasã fatã.
Johnny
fonte
30

Introduzido no Python 3.4, pathlibpossui um método realmente conveniente para ler texto de arquivos, da seguinte maneira:

from pathlib import Path
p = Path('my_text_file')
lines = p.read_text().splitlines()

(A splitlineschamada é o que a transforma de uma sequência que contém todo o conteúdo do arquivo para uma lista de linhas no arquivo).

pathlibtem muitas conveniências úteis nele. read_texté agradável e conciso, e você não precisa se preocupar em abrir e fechar o arquivo. Se tudo o que você precisa fazer com o arquivo é ler tudo de uma só vez, é uma boa escolha.

LangeHaare
fonte
29

Aqui está mais uma opção usando a compreensão da lista em arquivos;

lines = [line.rstrip() for line in open('file.txt')]

Essa deve ser a maneira mais eficiente, pois a maior parte do trabalho é feita dentro do interpretador Python.

user1833244
fonte
10
rstrip()potencialmente retira todo o espaço em branco à direita, não apenas o \n; use .rstrip('\n').
mklement0
Isso também não garante que o arquivo será fechado após a leitura em todas as implementações do Python (embora no CPython, a principal implementação do Python, seja).
Mark Amery
1
Essa deve ser a maneira mais eficiente, pois a maior parte do trabalho é feita dentro do interpretador Python. O que isso significa?
AMC
28
f = open("your_file.txt",'r')
out = f.readlines() # will append in the list out

Agora a variável out é uma lista (matriz) do que você deseja. Você pode fazer:

for line in out:
    print (line)

Ou:

for line in f:
    print (line)

Você obterá os mesmos resultados.

moldavo
fonte
27

Leia e grave arquivos de texto com Python 2 e Python 3; trabalha com Unicode

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Define data
lines = ['     A first string  ',
         'A Unicode sample: €',
         'German: äöüß']

# Write text file
with open('file.txt', 'w') as fp:
    fp.write('\n'.join(lines))

# Read text file
with open('file.txt', 'r') as fp:
    read_lines = fp.readlines()
    read_lines = [line.rstrip('\n') for line in read_lines]

print(lines == read_lines)

Coisas a serem observadas:

  • withé o chamado gerenciador de contexto . Ele garante que o arquivo aberto seja fechado novamente.
  • Todas as soluções aqui que simplesmente produzem .strip()ou .rstrip()deixarão de reproduzir, linescomo também retiram o espaço em branco.

Finais de arquivos comuns

.txt

Gravação / leitura de arquivos mais avançadas

Para seu aplicativo, o seguinte pode ser importante:

  • Suporte por outras linguagens de programação
  • Desempenho de leitura / escrita
  • Compacidade (tamanho do arquivo)

Consulte também: Comparação de formatos de serialização de dados

Caso você esteja procurando uma maneira de criar arquivos de configuração, leia meu pequeno artigo Arquivos de configuração em Python .

Martin Thoma
fonte
26

Outra opção é numpy.genfromtxt, por exemplo:

import numpy as np
data = np.genfromtxt("yourfile.dat",delimiter="\n")

Isso criará datauma matriz NumPy com tantas linhas quanto o seu arquivo.

atomh33ls
fonte
25

Se você deseja ler um arquivo na linha de comando ou no stdin, também pode usar o fileinputmódulo:

# reader.py
import fileinput

content = []
for line in fileinput.input():
    content.append(line.strip())

fileinput.close()

Passe os arquivos para ele da seguinte maneira:

$ python reader.py textfile.txt 

Leia mais aqui: http://docs.python.org/2/library/fileinput.html

oliland
fonte
20

A maneira mais simples de fazer isso

Uma maneira simples é:

  1. Leia o arquivo inteiro como uma string
  2. Divida a linha linha por linha

Em uma linha, isso daria:

lines = open('C:/path/file.txt').read().splitlines()

No entanto, essa é uma maneira bastante ineficiente, pois armazenará 2 versões do conteúdo na memória (provavelmente não é um grande problema para arquivos pequenos, mas ainda assim). [Obrigado Mark Amery].

Existem 2 maneiras mais fáceis:

  1. Usando o arquivo como um iterador
lines = list(open('C:/path/file.txt'))
# ... or if you want to have a list without EOL characters
lines = [l.rstrip() for l in open('C:/path/file.txt')]
  1. Se você estiver usando o Python 3.4 ou superior, use melhor pathlibpara criar um caminho para o seu arquivo que você poderia usar para outras operações no seu programa:
from pathlib import Path
file_path = Path("C:/path/file.txt") 
lines = file_path.read_text().split_lines()
# ... or ... 
lines = [l.rstrip() for l in file_path.open()]
Jean-Francois T.
fonte
Esta é uma péssima abordagem. Por um lado, ligar .read().splitlines()não é "mais simples" do que apenas ligar .readlines(). Por outro, é ineficiente em memória; você está desnecessariamente armazenando duas versões do conteúdo do arquivo (a única string retornada por .read()e a lista de strings retornadas por splitlines()) na memória de uma só vez.
Mark Amery
@MarkAmery True. Obrigado por destacar isso. Eu atualizei minha resposta.
Jean-Francois T.
14

Basta usar as funções splitlines (). Aqui está um exemplo.

inp = "file.txt"
data = open(inp)
dat = data.read()
lst = dat.splitlines()
print lst
# print(lst) # for python 3

Na saída, você terá a lista de linhas.

Abdullah Bilal
fonte
Memória ineficiente em comparação com o uso .readlines(). Isso coloca duas cópias do conteúdo do arquivo na memória de uma só vez (uma como uma única cadeia enorme, uma como uma lista de linhas).
Mark Amery
11

Se você deseja encontrar um arquivo muito grande / grande e deseja ler mais rapidamente (imagine que você esteja em uma competição de codificação Topcoder / Hackerrank), pode ler um pedaço consideravelmente maior de linhas em um buffer de memória ao mesmo tempo, em vez de apenas itere linha por linha no nível do arquivo.

buffersize = 2**16
with open(path) as f: 
    while True:
        lines_buffer = f.readlines(buffersize)
        if not lines_buffer:
            break
        for line in lines_buffer:
            process(line)
pambda
fonte
o que process (line) faz? Eu recebo um erro que não existe essa variável definida. Eu acho que algo precisa ser importado e tentei importar o multiprocessing.Process, mas não é isso, eu acho. Você poderia por favor elaborar? Graças
Newskooler
1
process(line)é uma função que você precisa implementar para processar os dados. por exemplo, em vez dessa linha, se você usar print(line), ela imprimirá cada linha do lines_buffer.
precisa saber é o seguinte
f.readlines (tamanho do buffer) retorna um buffer imutável. se você quiser ler diretamente no seu buffer, precisará usar a função readinto (). Eu serei muito mais rápido.
David Dehghan
7

As maneiras mais fáceis de fazer isso com alguns benefícios adicionais são:

lines = list(open('filename'))

ou

lines = tuple(open('filename'))

ou

lines = set(open('filename'))

No caso de set, devemos lembrar que não temos a ordem das linhas preservada e nos livramos das linhas duplicadas.

Abaixo, adicionei um importante complemento do @MarkAmery :

Como você não está chamando .closeo objeto de arquivo nem está usando uma withinstrução, em algumas implementações do Python, o arquivo pode não ser fechado após a leitura e seu processo vazará um identificador de arquivo aberto .

No CPython (a implementação normal do Python usada pela maioria das pessoas), isso não é um problema, já que o objeto do arquivo é imediatamente coletado pelo lixo e isso fecha o arquivo, mas, no entanto, geralmente é considerado uma boa prática fazer algo como :

with open('filename') as f: lines = list(f) 

para garantir que o arquivo seja fechado, independentemente da implementação do Python que você está usando.

simhumileco
fonte
1
Como você não está chamando .closeo objeto de arquivo nem está usando uma withinstrução, em algumas implementações do Python o arquivo pode não ser fechado após a leitura e seu processo vazará um identificador de arquivo aberto. No CPython (a implementação normal do Python usada pela maioria das pessoas), isso não é um problema, já que o objeto do arquivo é imediatamente coletado pelo lixo e isso fecha o arquivo, mas, no entanto, geralmente é considerado uma boa prática fazer algo como with open('filename') as f: lines = list(f)garantir que o arquivo é fechado independentemente da implementação do Python que você está usando.
Mark Amery
Obrigado pelo seu ótimo comentário @MarkAmery! Eu realmente gostei disso.
simhumileco
1
@simhumileco Por que a melhor (correta) solução durou?
AMC
@AMC porque, primeiro, eu queria mostrar maneiras mais simples e consistentes de raciocínio.
simhumileco 9/01
Além disso, espero que minha resposta seja feita para que seja curta e fácil de ler.
simhumileco 9/01
4

Usa isto:

import pandas as pd
data = pd.read_csv(filename) # You can also add parameters such as header, sep, etc.
array = data.values

dataé um tipo de quadro de dados e usa valores para obter ndarray. Você também pode obter uma lista usando array.tolist().

Zero
fonte
pandas.read_csv()é para ler dados CSV , como é apropriado aqui?
AMC
4

Esboço e Resumo

Com a filename, manipulando o arquivo de um Path(filename)objeto ou diretamente com open(filename) as f, execute um dos seguintes procedimentos:

  • list(fileinput.input(filename))
  • usando with path.open() as f, liguef.readlines()
  • list(f)
  • path.read_text().splitlines()
  • path.read_text().splitlines(keepends=True)
  • iterar sobre fileinput.inputou felist.append cada uma linha de cada vez
  • passar fpara um limitelist.extend método
  • usar fem uma compreensão de lista

Eu explico o caso de uso de cada um abaixo.

No Python, como leio um arquivo linha por linha?

Esta é uma excelente pergunta. Primeiro, vamos criar alguns dados de exemplo:

from pathlib import Path
Path('filename').write_text('foo\nbar\nbaz')

Os objetos de arquivo são iteradores preguiçosos; portanto, apenas itere sobre ele.

filename = 'filename'
with open(filename) as f:
    for line in f:
        line # do something with the line

Como alternativa, se você tiver vários arquivos, use fileinput.inputoutro iterador lento. Com apenas um arquivo:

import fileinput

for line in fileinput.input(filename): 
    line # process the line

ou para vários arquivos, passe uma lista de nomes de arquivos:

for line in fileinput.input([filename]*2): 
    line # process the line

Novamente, fe fileinput.inputacima, ambos são / retornam iteradores preguiçosos. Você só pode usar um iterador uma vez; portanto, para fornecer código funcional e evitar a verbosidade, usarei o que é um pouco mais conciso fileinput.input(filename)a partir daqui.

No Python, como leio um arquivo linha por linha em uma lista?

Ah, mas você quer isso em uma lista por algum motivo? Eu evitaria isso, se possível. Mas se você insistir ... basta passar o resultado de fileinput.input(filename)para list:

list(fileinput.input(filename))

Outra resposta direta é a chamada f.readlines, que retorna o conteúdo do arquivo (até um hintnúmero opcional de caracteres, para que você possa dividi-lo em várias listas dessa maneira).

Você pode acessar esse objeto de arquivo de duas maneiras. Uma maneira é passar o nome do arquivo para o openbuilt-in:

filename = 'filename'

with open(filename) as f:
    f.readlines()

ou usando o novo objeto Path do pathlibmódulo (do qual me apaixonei e utilizarei daqui em diante):

from pathlib import Path

path = Path(filename)

with path.open() as f:
    f.readlines()

list também consumirá o iterador de arquivos e retornará uma lista - um método bastante direto:

with path.open() as f:
    list(f)

Se você não se importa de ler o texto inteiro na memória como uma única string antes de dividi-la, faça isso como uma linha com o Pathobjeto e o splitlines()método string. Por padrão, splitlinesremove as novas linhas:

path.read_text().splitlines()

Se você deseja manter as novas linhas, passe keepends=True:

path.read_text().splitlines(keepends=True)

Quero ler o arquivo linha por linha e anexar cada linha ao final da lista.

Agora, isso é um pouco tolo de pedir, já que demonstramos o resultado final facilmente com vários métodos. Mas pode ser necessário filtrar ou operar nas linhas à medida que você faz sua lista, portanto, vamos aceitar essa solicitação.

O uso list.appendpermitiria filtrar ou operar em cada linha antes de anexá-la:

line_list = []
for line in fileinput.input(filename):
    line_list.append(line)

line_list

Usar list.extendseria um pouco mais direto e talvez útil se você tiver uma lista preexistente:

line_list = []
line_list.extend(fileinput.input(filename))
line_list

Ou, mais lingüisticamente, poderíamos usar uma compreensão de lista e mapear e filtrar dentro dela, se desejável:

[line for line in fileinput.input(filename)]

Ou ainda mais diretamente, para fechar o círculo, basta passar para a lista para criar uma nova lista diretamente sem operar nas linhas:

list(fileinput.input(filename))

Conclusão

Você já viu várias maneiras de inserir linhas de um arquivo em uma lista, mas eu recomendo que você evite materializar grandes quantidades de dados em uma lista e, em vez disso, use a iteração lenta do Python para processar os dados, se possível.

Ou seja, prefira fileinput.inputou with path.open() as f.

Aaron Hall
fonte
4

Caso também existam linhas vazias no documento, gosto de ler o conteúdo e passá-lo filterpara evitar elementos de string vazios

with open(myFile, "r") as f:
    excludeFileContent = list(filter(None, f.read().splitlines()))
jeanggi90
fonte
1
Isso é antitônico, tenha cuidado.
AMC
3

Você também pode usar o comando loadtxt no NumPy. Isso verifica menos condições que o genfromtxt, portanto, pode ser mais rápido.

import numpy
data = numpy.loadtxt(filename, delimiter="\n")
asampat3090
fonte
2

Eu gosto de usar o seguinte. Lendo as linhas imediatamente.

contents = []
for line in open(filepath, 'r').readlines():
    contents.append(line.strip())

Ou usando a compreensão da lista:

contents = [line.strip() for line in open(filepath, 'r').readlines()]
Daniel
fonte
2
Não há necessidade readlines(), o que gera uma penalidade de memória. Você pode simplesmente removê-lo, pois a iteração sobre um arquivo (texto) fornece cada linha por vez.
Eric O Lebigot
2
Você deve usar uma withinstrução para abrir (e fechar implicitamente) o arquivo.
21818 Aran-Fey
2

Eu tentaria um dos métodos abaixo mencionados. O arquivo de exemplo que eu uso tem o nome dummy.txt. Você pode encontrar o arquivo aqui . Presumo que o arquivo esteja no mesmo diretório que o código (você pode alterar fpathpara incluir o nome do arquivo e o caminho da pasta adequados).

Nos exemplos abaixo mencionados, a lista que você deseja é fornecida por lst.

1.> Primeiro método :

fpath = 'dummy.txt'
with open(fpath, "r") as f: lst = [line.rstrip('\n \t') for line in f]

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

2.> No segundo método , pode-se usar o módulo csv.reader da Python Standard Library :

import csv
fpath = 'dummy.txt'
with open(fpath) as csv_file:
    csv_reader = csv.reader(csv_file, delimiter='   ')
    lst = [row[0] for row in csv_reader] 

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

Você pode usar um dos dois métodos. O tempo necessário para a criação de lsté quase igual nos dois métodos.

Siddharth Satpathy
fonte
1
Qual é a vantagem da segunda abordagem? Por que chamar uma biblioteca adicional, que adiciona casos de borda (o delimitador e aspas)?
Charlie Harding
Para que serve o delimiter=' 'argumento?
AMC
2

Aqui está uma classe de biblioteca auxiliar Python (3) que eu uso para simplificar a E / S do arquivo:

import os

# handle files using a callback method, prevents repetition
def _FileIO__file_handler(file_path, mode, callback = lambda f: None):
  f = open(file_path, mode)
  try:
    return callback(f)
  except Exception as e:
    raise IOError("Failed to %s file" % ["write to", "read from"][mode.lower() in "r rb r+".split(" ")])
  finally:
    f.close()


class FileIO:
  # return the contents of a file
  def read(file_path, mode = "r"):
    return __file_handler(file_path, mode, lambda rf: rf.read())

  # get the lines of a file
  def lines(file_path, mode = "r", filter_fn = lambda line: len(line) > 0):
    return [line for line in FileIO.read(file_path, mode).strip().split("\n") if filter_fn(line)]

  # create or update a file (NOTE: can also be used to replace a file's original content)
  def write(file_path, new_content, mode = "w"):
    return __file_handler(file_path, mode, lambda wf: wf.write(new_content))

  # delete a file (if it exists)
  def delete(file_path):
    return os.remove() if os.path.isfile(file_path) else None

Você usaria a FileIO.linesfunção, assim:

file_ext_lines = FileIO.lines("./path/to/file.ext"):
for i, line in enumerate(file_ext_lines):
  print("Line {}: {}".format(i + 1, line))

Lembre-se de que os parâmetros mode( "r"por padrão) e filter_fn(verifica se há linhas vazias por padrão) são opcionais.

Você pode até mesmo remover as read, writee deletemétodos e apenas deixar o FileIO.lines, ou mesmo transformá-lo em um método separado chamado read_lines.

LogicalBranch
fonte
É lines = FileIO.lines(path)realmente mais simples do with open(path) as f: lines = f.readlines()que justificar a existência desse ajudante? Você economiza 17 caracteres por chamada. (E na maioria das vezes, por motivos de desempenho e memória, você desejará repetir um objeto de arquivo diretamente, em vez de ler suas linhas em uma lista de qualquer maneira, para que você nem queira usá-lo com frequência!) muitas vezes é fã de criar poucas funções utilitárias, mas essa me parece que está criando desnecessariamente uma nova maneira de escrever algo que já é curto e fácil com a biblioteca padrão.
Mark Amery
Além do que o @MarkAmery disse, por que usar uma classe para isso?
AMC
1

Versão da linha de comando

#!/bin/python3
import os
import sys
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
filename = dname + sys.argv[1]
arr = open(filename).read().split("\n") 
print(arr)

Correr com:

python3 somefile.py input_file_name.txt
jasonleonhard
fonte