Como ler um arquivo sem novas linhas?

374

Em Python, chamando

temp = open(filename,'r').readlines()

resulta em uma lista na qual cada elemento é uma linha no arquivo. É um pouco estúpido, mas ainda assim: readlines()também escreve caracteres de nova linha para cada elemento, algo que eu não desejo que aconteça.

Como posso evitá-lo?

Yotam
fonte
4
Uso tiras [l.strip('\n\r') for l in temp]. Ou até rstrip. E já que a iteração aqui pode ser em in openvez de in temp.
perfil completo de gorlum
11
Seria bom se no Python 3 houvesse um valor para definir o newlineargumento do open para as novas linhas finais.
Jxramos # 03/17

Respostas:

554

Você pode ler o arquivo inteiro e dividir linhas usando str.splitlines:

temp = file.read().splitlines()

Ou você pode retirar a nova linha manualmente:

temp = [line[:-1] for line in file]

Nota: esta última solução funciona apenas se o arquivo terminar com uma nova linha, caso contrário, a última linha perderá um caractere.

Esta suposição é verdade na maioria dos casos (especialmente para arquivos criados por editores de texto, que muitas vezes fazer adicionar uma nova linha terminando de qualquer maneira).

Se você deseja evitar isso, pode adicionar uma nova linha no final do arquivo:

with open(the_file, 'r+') as f:
    f.seek(-1, 2)  # go at the end of the file
    if f.read(1) != '\n':
        # add missing newline if not already present
        f.write('\n')
        f.flush()
        f.seek(0)
    lines = [line[:-1] for line in f]

Ou uma alternativa mais simples é stripa nova linha:

[line.rstrip('\n') for line in file]

Ou ainda, embora bastante ilegível:

[line[:-(line[-1] == '\n') or len(line)+1] for line in file]

O que explora o fato de que o valor de retorno de ornão é um booleano, mas o objeto que foi avaliado como verdadeiro ou falso.


O readlinesmétodo é realmente equivalente a:

def readlines(self):
    lines = []
    for line in iter(self.readline, ''):
        lines.append(line)
    return lines

# or equivalently

def readlines(self):
    lines = []
    while True:
        line = self.readline()
        if not line:
            break
        lines.append(line)
    return lines

Desde readline()mantém a nova linha também readlines()mantém.

Nota: a simetria readlines()no writelines()método não adiciona novas linhas finais, f2.writelines(f.readlines())produz uma cópia exata de fin f2.

Bakuriu
fonte
11
Observe que [line.rstrip('\n') for line in file]removerá mais de um final \n.
23615 Wes Wesley
11
Mais simplesmente, [line[:-(line[-1] == '\n') or len(line)+1] for line in file]poderia ser [line[:-(line[-1] == '\n') or None] for line in file].
Wes Turner
10
Essas soluções leem o arquivo inteiro na memória. Alterar os colchetes da compreensão da lista para parênteses gera uma expressão geradora que permite iterar sobre o arquivo uma linha por vez: for line in (x.strip() for x in f):
Joseph Sheedy
2
@velotron Esse não é realmente o objetivo da pergunta / resposta. Além disso, lembre-se de que withfecha os arquivos quando o bloco termina, o que significa que você não pode fazer with open(...) as f: lines = (line for line in f)e usar linesfora do servidor withporque receberá um erro de E / S. Você pode ficar preguiçoso usando um genexp, mas deve consumi-lo antes de fechar o arquivo.
Bakuriu 20/01
@WesTurner. Mas não haverá mais de uma nova linha final. A nova linha extra vai fazer parte da próxima linha vazia
Mad Físico
38
temp = open(filename,'r').read().split('\n')
vivek
fonte
14
O que aconteceria com as \r\nnovas linhas? ;)
Wolph 8/09/12
26
O Python lida automaticamente com novas linhas universais, portanto, .split('\n')será dividido corretamente, independentemente da convenção da nova linha. É importante que você leia o arquivo no modo binário, nesse caso splitlines()lida com novas linhas universais e split('\n')não.
Bakuriu 8/09/12
7
E há sempre os.linesep:)
askewchan
11
@ LarsH, ajudaria em algumas circunstâncias, nas \r\nterminações da linha do sistema não são convertidas para \n, sejam lidas como texto ou binárias, portanto os.linesepfuncionariam onde \nnão. Mas splitlinesé claramente a melhor escolha, no caso de você mencionar onde o arquivo não corresponde ao sistema operacional. Na verdade, eu o mencionei principalmente no caso de as pessoas que olham para esta discussão desconhecem sua existência.
askewchan
11
@askewchan Talvez você esteja usando uma versão desatualizada do Python. Acredito que a partir do Python 3, as novas linhas universais sejam ativadas por padrão, ou seja, \r\nseriam convertidas para arquivos de texto, mesmo quando você estiver executando no Linux.
Arthur Tacca
13

outro exemplo:

Lendo o arquivo uma linha por vez. Removendo caracteres indesejados do final da stringstr.rstrip(chars)

with open(filename, 'r') as fileobj:
    for row in fileobj:
        print( row.rstrip('\n') )

veja também str.strip([chars])estr.lstrip([chars])

(python> = 2.0)

O-9
fonte
10
temp = open(filename,'r').read().splitlines()
Marcel
fonte
5
Tem certeza de que isso fecha o arquivo? Eu acho que não, por isso não é realmente um one-liner ...
Ray Hulha
9

Eu acho que essa é a melhor opção.

temp = [line.strip() for line in file.readlines()]
RENZO
fonte
8
Essa solução também remove os espaços à esquerda e à direita, que não se destinam.
Roland Illig 01/05/19
A compreensão é muito boa, no entanto. Pelo menos no Python 3, pode-se usar temp = [line.rstrip() for line in file.readlines()]para obter o que as notas do @Roland_Illig se destinam.
bballdave025 11/01
Se você vai repetir todas as linhas, por que não tão preguiçosamente? Com .readlines(), você efetivamente itera o arquivo inteiro duas vezes.
AMC
1

Tente o seguinte:

u=open("url.txt","r")  
url=u.read().replace('\n','')  
print(url)  
Nitesh Soni
fonte
4
Embora esse trecho de código possa resolver a questão, incluir uma explicação realmente ajuda a melhorar a qualidade da sua postagem. Lembre-se de que você está respondendo à pergunta dos leitores no futuro e essas pessoas podem não saber os motivos da sua sugestão de código. Tente também não sobrecarregar seu código com comentários explicativos, pois isso reduz a legibilidade do código e das explicações!
Adeus StackExchange
Não vejo por que alguém deveria usar isso em algumas soluções alternativas.
AMC
-1
my_file = open("first_file.txt", "r")
for line in my_file.readlines():
    if line[-1:] == "\n":
        print(line[:-1])
    else:
        print(line)
my_file.close() 
Necriss
fonte
3
Por favor, adicione algumas explicações para que sejam úteis para outras pessoas.
precisa saber é o seguinte
Você deve usar um gerenciador de contexto para manipular o objeto de arquivo e iterar diretamente sobre o arquivo. Ao usar .readlines()dessa maneira, você efetivamente itera o arquivo inteiro duas vezes.
AMC
-2
import csv

with open(filename) as f:
    csvreader = csv.reader(f)
    for line in csvreader:
         print(line[0])
srus
fonte
2
Mas e se a linha tiver uma vírgula?
gilch
-8
def getText():
    file=open("ex1.txt","r");

    names=file.read().split("\n");
    for x,word in enumerate(names):
        if(len(word)>=20):
            return 0;
            print "length of ",word,"is over 20"
            break;
        if(x==20):
            return 0;
            break;
    else:
        return names;


def show(names):
    for word in names:
        len_set=len(set(word))
        print word," ",len_set


for i in range(1):

    names=getText();
    if(names!=0):
        show(names);
    else:
        break;
user4730171
fonte