¿Cómo leer un archivo sin saltos de línea?

374

En Python, llamando

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

da como resultado una lista en la que cada elemento es una línea en el archivo. Es un poco estúpido pero aún así: readlines()también escribe caracteres de nueva línea en cada elemento, algo que no deseo que suceda.

¿Cómo puedo evitarlo?

Yotam
fuente
44
Uso tira: [l.strip('\n\r') for l in temp]. O incluso rstrip. Y desde la iteración aquí puede ser en in openlugar de in temp.
gorlum0
11
Sería bueno si en Python 3 hubiera un valor para establecer el newlineargumento de open en esas nuevas líneas finales.
jxramos

Respuestas:

555

Puede leer todo el archivo y dividir líneas usando str.splitlines:

temp = file.read().splitlines()

O puede quitar la nueva línea a mano:

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

Nota: esta última solución solo funciona si el archivo termina con una nueva línea; de lo contrario, la última línea perderá un carácter.

Este supuesto es cierto en la mayoría de los casos (especialmente para los archivos creados por los editores de texto, que a menudo hacen añadir una nueva línea que termina de todos modos).

Si desea evitar esto, puede agregar una nueva línea al final del archivo:

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]

O una alternativa más simple es stripla nueva línea:

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

O incluso, aunque bastante ilegible:

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

Lo que explota el hecho de que el valor de retorno de orno es un valor booleano, sino el objeto que se evaluó como verdadero o falso.


El readlinesmétodo es en realidad 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

Como readline()mantiene la nueva línea también la readlines()mantiene.

Nota: para la simetría readlines()del writelines()método no se agregan nuevas líneas finales, por lo que f2.writelines(f.readlines())produce una copia exacta de fin f2.

Bakuriu
fuente
1
Tenga en cuenta que [line.rstrip('\n') for line in file]eliminará más de un final \n.
Wes Turner
1
Más simplemente, [line[:-(line[-1] == '\n') or len(line)+1] for line in file]podría ser en su lugar [line[:-(line[-1] == '\n') or None] for line in file].
Wes Turner
10
Estas soluciones leen todo el archivo en la memoria. Cambiar los corchetes de una comprensión de lista a paréntesis crea una expresión generadora que le permite iterar sobre el archivo una línea a la vez: for line in (x.strip() for x in f):
Joseph Sheedy
2
@velotron Ese no es realmente el punto de la pregunta / respuesta. Además: tenga en cuenta que withcierra los archivos cuando finaliza el bloque, lo que significa que no puede hacerlo with open(...) as f: lines = (line for line in f)y usarlos linesfuera withporque obtendrá un error de E / S. Puede ser flojo usando un genexp, pero debe consumirlo antes de cerrar el archivo.
Bakuriu
@WesTurner. Pero no habrá más de una nueva línea final. La nueva línea adicional será parte de la próxima línea vacía
Mad Physicist el
38
temp = open(filename,'r').read().split('\n')
vivek
fuente
14
¿Qué pasaría con las \r\nnuevas líneas? ;)
Wolph
26
Python maneja automáticamente las nuevas líneas universales, por .split('\n')lo tanto, se dividirá correctamente, independientemente de la convención de nueva línea. Importaría si lees el archivo en modo binario, en ese caso splitlines()maneja nuevas líneas universales mientras split('\n')que no lo hace.
Bakuriu
77
Y siempre hay os.linesep:)
askewchan
1
@LarsH, ayudaría en algunas circunstancias, en mi sistema \r\n, las terminaciones de línea no se convierten \n, ya sea como texto o binario, por os.lineseplo que funcionaría donde \nno. Pero splitlineses claramente la mejor opción, en el caso de que mencione dónde el archivo no coincide con el sistema operativo. Realmente lo mencioné principalmente en caso de que las personas que miraban esta discusión no supieran de su existencia.
askewchan
1
@askewchan Quizás estés usando una versión desactualizada de Python. Creo que a partir de Python 3, las nuevas líneas universales están habilitadas de forma predeterminada, es decir \r\n, se convertirían para archivos de texto incluso cuando esté ejecutando en Linux.
Arthur Tacca
13

otro ejemplo:

Leyendo el archivo una fila a la vez. Eliminar caracteres no deseados con desde el final de la cadenastr.rstrip(chars)

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

ver también str.strip([chars])ystr.lstrip([chars])

(python> = 2.0)

O-9
fuente
10
temp = open(filename,'r').read().splitlines()
Marcel
fuente
55
¿Estás seguro de que esto cierra el archivo? Creo que no, así que en realidad no es una
frase
9

Creo que esta es la mejor opción.

temp = [line.strip() for line in file.readlines()]
Renzo
fuente
8
Esta solución también elimina los espacios iniciales y finales, que no están destinados.
Roland Illig
Sin embargo, la comprensión es realmente agradable. Al menos con Python 3, se puede usar temp = [line.rstrip() for line in file.readlines()]para obtener lo que se pretende con las notas de @Roland_Illig.
bballdave025
Si va a iterar sobre todas las líneas, ¿por qué no hacerlo tan perezosamente? Con .readlines(), estás iterando efectivamente sobre todo el archivo dos veces.
AMC
1

Prueba esto:

u=open("url.txt","r")  
url=u.read().replace('\n','')  
print(url)  
Nitesh Soni
fuente
44
Si bien este fragmento de código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no conocer los motivos de su sugerencia de código. ¡Intente también no saturar su código con comentarios explicativos, ya que esto reduce la legibilidad tanto del código como de las explicaciones!
Adiós StackExchange
No veo por qué alguien debería usar esto sobre algunas de las soluciones 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
fuente
3
Agregue alguna explicación para que sea útil para otros.
samuellawrentz
Debe usar un administrador de contexto para manejar el objeto del archivo e iterar sobre el archivo directamente. Al usarlo de .readlines()esta manera, está iterando efectivamente sobre todo el archivo dos veces.
AMC
-2
import csv

with open(filename) as f:
    csvreader = csv.reader(f)
    for line in csvreader:
         print(line[0])
srus
fuente
2
Pero, ¿qué pasa si la línea tiene una coma?
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;
usuario4730171
fuente