La meilleure méthode pour lire les fichiers délimités par des retours à la ligne et supprimer les retours à la ligne?

84

J'essaie de déterminer la meilleure façon de gérer la suppression des nouvelles lignes lors de la lecture de fichiers délimités par les nouvelles lignes en Python.

Ce que j'ai trouvé est le code suivant, incluez du code jetable à tester.

import os

def getfile(filename,results):
   f = open(filename)
   filecontents = f.readlines()
   for line in filecontents:
     foo = line.strip('\n')
     results.append(foo)
   return results

blahblah = []

getfile('/tmp/foo',blahblah)

for x in blahblah:
    print x

Suggestions?

Solarce
la source
qu'en est-il de l'utilisation de split ("/ n")?
jle
1
Identique à: stackoverflow.com/questions/339537/…
Vijay Dev
Je pense qu'il serait préférable de fermer également le fichier
Paweł Prażak

Réponses:

196
lines = open(filename).read().splitlines()
Curt Hagenlocher
la source
Cette réponse fait ce que je voulais, je suis sûr que je vais devoir ajouter une vérification des erreurs et autres, mais pour ce besoin spécifique, c'est génial. Merci à tous pour vos réponses!
solarce
J'aime ça mais comment fermez-vous le fichier si vous ne sauvegardez pas le descripteur de fichier? Ou est-il automatiquement fermé?
IJ Kennedy
6
Avec CPython, le nombre de références de l'objet fichier passera à zéro une fois qu'il n'est plus utilisé et le fichier sera automatiquement fermé. Pour les implémentations purement GC telles que Jython et IronPython, le fichier peut ne pas être fermé jusqu'à ce que le GC s'exécute - donc cette variation laconique peut ne pas être optimale.
Curt Hagenlocher
2
Sur Mac OS X 10.7.5 avec 8 Go de RAM, je peux lire des fichiers jusqu'à 2047 Mo (ma définition: 1 Mo = 1024 x 1024 octets). 2048 Mo lancera une exception MemoryError.
Hai Vu
1
@WKPlus Excellente question - la réponse est "ça dépend" stackoverflow.com/a/15099341/994153 (CPython le fermera puisque le nombre de références tombe à zéro, mais d'autres implémentations Python pourraient ne pas le fermer, il vaut donc mieux le rendre explicite )
Colin D Bennett
23

Voici un générateur qui fait ce que vous avez demandé. Dans ce cas, l'utilisation de rstrip est suffisante et légèrement plus rapide que la bande.

lines = (line.rstrip('\n') for line in open(filename))

Cependant, vous voudrez probablement l'utiliser pour vous débarrasser également des espaces de fin.

lines = (line.rstrip() for line in open(filename))
TimoLinna
la source
Ne devrait-il pas être [] autour du RHS, pas ()?
andrewb
8
@andrewb Using () donne une expression de générateur, qui n'utilise pas autant de mémoire que using [] (une compréhension de liste.)
Jonathan Hartley
9

Que pensez-vous de cette approche?

with open(filename) as data:
    datalines = (line.rstrip('\r\n') for line in data)
    for line in datalines:
        ...do something awesome...

L'expression du générateur évite de charger tout le fichier en mémoire et withassure la fermeture du fichier

Paweł Prażak
la source
C'est essentiellement la même chose que la réponse de @ TimoLinna publiée des années à l'avance ...
martineau
8
for line in file('/tmp/foo'):
    print line.strip('\n')
David Z
la source
4

Utilisez simplement des expressions génératrices:

blahblah = (l.rstrip() for l in open(filename))
for x in blahblah:
    print x

Je tiens également à vous déconseiller de lire le fichier entier en mémoire - le bouclage sur des générateurs est beaucoup plus efficace sur de grands ensembles de données.


la source
3

Je l'utilise

def cleaned( aFile ):
    for line in aFile:
        yield line.strip()

Ensuite, je peux faire des choses comme ça.

lines = list( cleaned( open("file","r") ) )

Ou, je peux étendre nettoyé avec des fonctions supplémentaires pour, par exemple, supprimer des lignes vides ou sauter des lignes de commentaire ou autre.

S.Lott
la source
2

Je le ferais comme ceci:

f = open('test.txt')
l = [l for l in f.readlines() if l.strip()]
f.close()
print l
S.Lott
la source
Bien que la réponse de Curt Hagenlocher soit techniquement meilleure, cette réponse est un bon point de départ si vous devez ajouter un autre traitement à chaque ligne.
TomOnTime
Je ne sais pas s'il était destiné à filtrer les lignes vides, mais c'est plus concis que ... if l.strip() is not '', ce dont j'ai besoin dans mon cas.
Zach Young