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.