Najlepsza metoda czytania plików rozdzielanych znakami nowej linii i odrzucania nowych linii?


84

Próbuję określić najlepszy sposób na pozbycie się znaków nowej linii podczas czytania w plikach rozdzielanych znakami nowej linii w Pythonie.

To, co wymyśliłem, to następujący kod, zawiera kod jednorazowy do przetestowania.

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

Propozycje?


a co z użyciem podziału („/ n”)?
JLE


Myślę, że też lepiej byłoby zamknąć teczkę
Paweł Prażak 08.08.11

Odpowiedzi:


196
lines = open(filename).read().splitlines()

1
Ta odpowiedź robi to, do czego dążyłem, jestem pewien, że będę musiał dodać trochę sprawdzania błędów i tak dalej, ale dla tej konkretnej potrzeby jest świetny. Dziękuję wszystkim za udzielenie odpowiedzi!
solarce

Podoba mi się to, ale jak zamknąć plik, jeśli nie zapisujesz uchwytu pliku? Czy jest automatycznie zamykana?
IJ Kennedy

6
W CPythonie liczba odwołań dla obiektu pliku spadnie do zera, gdy nie będzie już używany, a plik zostanie automatycznie zamknięty. W przypadku implementacji czysto GC, takich jak Jython i IronPython, plik może nie zostać zamknięty do czasu uruchomienia GC - więc ta zwięzła odmiana może nie być optymalna.
Curt Hagenlocher

2
W systemie Mac OS X 10.7.5 z 8 GB pamięci RAM mogę odczytać plik do 2047 MB ​​(moja definicja: 1 MB = 1024 x 1024 bajtów). 2048 MB spowoduje zgłoszenie wyjątku MemoryError.
Hai Vu

1
@WKPlus Doskonałe pytanie - odpowiedź brzmi "to zależy" stackoverflow.com/a/15099341/994153 (CPython zamknie to, ponieważ liczba odwołań spadnie do zera, ale inne implementacje Pythona mogą go nie zamknąć, więc najlepiej jest to wyraźnie określić )
Colin D Bennett

23

Oto generator, który robi to, o co prosiłeś. W takim przypadku użycie rstrip jest wystarczające i nieco szybsze niż strip.

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

Jednak najprawdopodobniej będziesz chciał użyć tego również do pozbycia się końcowych białych znaków.

lines = (line.rstrip() for line in open(filename))

Czy nie powinno być [] wokół RHS, a nie ()?
andrewb

8
@andrewb Użycie () daje wyrażenie generatora, które nie zużywa tyle pamięci, co użycie [] (rozumienie listy).
Jonathan Hartley

9

Co myślisz o tym podejściu?

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

Wyrażenie generatora pozwala uniknąć ładowania całego pliku do pamięci i withzapewnia zamknięcie pliku


To jest w zasadzie taka sama jak @ TimoLinna za odpowiedź wysłane lat wcześniej ...
martineau


4

Po prostu użyj wyrażeń generatora:

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

Chciałbym również odradzić wczytywanie całego pliku w pamięci - pętla nad generatorami jest znacznie wydajniejsza w przypadku dużych zbiorów danych.


3

używam tego

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

Wtedy mogę robić takie rzeczy.

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

Lub mogę rozszerzyć funkcję wyczyszczoną o dodatkowe funkcje, na przykład, aby upuścić puste wiersze lub pominąć wiersze komentarzy lub cokolwiek innego.


2

Zrobiłbym to tak:

f = open('test.txt')
l = [l for l in f.readlines() if l.strip()]
f.close()
print l

Chociaż odpowiedź Curta Hagenlochera jest technicznie lepsza, to ta odpowiedź jest dobrym punktem wyjścia, jeśli chcesz dodać inne przetwarzanie do każdej linii.
TomOnTime

Nie jestem pewien, czy miał na celu filtrowanie pustych wierszy, ale jest to bardziej zwięzłe niż ... if l.strip() is not '', czego potrzebuję w moim przypadku.
Zach Young,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.