Лучший метод для чтения файлов с разделителями новой строки и отбрасывания новых строк?

84

Я пытаюсь определить лучший способ избавиться от символов новой строки при чтении файлов с разделителями на новую строку в Python.

Я придумал следующий код, включая одноразовый код для тестирования.

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

Предложения?

Solarce
источник
как насчет использования split ("/ n")?
jle
1
То же, что и: stackoverflow.com/questions/339537/…
Виджей Дев,
Думаю, было бы лучше закрыть и файл
Павел Пражак

Ответы:

196
lines = open(filename).read().splitlines()
Курт Хагенлохер
источник
1
Этот ответ делает то, что я хотел, я уверен, что мне нужно добавить проверку ошибок и тому подобное, но для этой конкретной потребности это здорово. Спасибо всем за ответы!
solarce,
Мне это нравится, но как закрыть файл, если вы не сохраняете дескриптор файла? Или он автоматически закрывается?
Эй Джей Кеннеди
6
С CPython счетчик ссылок для файлового объекта будет равен нулю, когда он больше не используется, и файл будет автоматически закрыт. Для реализаций с чисто GC, таких как Jython и IronPython, файл не может быть закрыт до запуска GC, поэтому этот краткий вариант может быть неоптимальным.
Курт Хагенлохер,
2
В Mac OS X 10.7.5 с 8 ГБ ОЗУ я могу прочитать файл размером до 2047 МБ (мое определение: 1 МБ = 1024 x 1024 байта). 2048MB вызовет исключение MemoryError.
Хай Ву
1
@WKPlus Отличный вопрос - ответ - «это зависит» stackoverflow.com/a/15099341/994153 (CPython закроет его, так как счетчик ссылок упадет до нуля, но другие реализации Python могут не закрыть его, поэтому лучше сделать это явным )
Колин Д. Беннетт
23

Вот генератор, который делает то, что вы просили. В этом случае достаточно использовать rstrip и немного быстрее, чем strip.

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

Однако вы, скорее всего, захотите использовать это, чтобы избавиться и от конечных пробелов.

lines = (line.rstrip() for line in open(filename))
ТимоЛинна
источник
Разве это не должно быть [] вокруг RHS, а не ()?
andrewb
8
@andrewb Использование () дает выражение генератора, которое не использует столько памяти, сколько использует [] (понимание списка.)
Джонатан Хартли
9

Что вы думаете об этом подходе?

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

Выражение генератора избегает загрузки всего файла в память и withобеспечивает закрытие файла

Павел Пражак
источник
По сути, это то же самое, что и ответ @ TimoLinna, опубликованный за несколько лет до этого ...
Мартино
8
for line in file('/tmp/foo'):
    print line.strip('\n')
Дэвид З
источник
4

Просто используйте выражения генератора:

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

Также я хочу посоветовать вам не читать весь файл в памяти - цикл по генераторам намного эффективнее для больших наборов данных.


источник
3

Я использую это

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

Тогда я смогу делать такие вещи.

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

Или я могу расширить clean с помощью дополнительных функций, например, для удаления пустых строк или пропуска строк комментариев или чего-то еще.

С.Лотт
источник
2

Я бы сделал так:

f = open('test.txt')
l = [l for l in f.readlines() if l.strip()]
f.close()
print l
С.Лотт
источник
Хотя ответ Курта Хагенлохера технически лучше, этот ответ является хорошей отправной точкой, если вам нужно добавить другую обработку в каждую строку.
TomOnTime
Не уверен, что это было предназначено для фильтрации пустых строк, но это более сжато, чем то ... if l.strip() is not '', что мне нужно в моем случае.
Zach Young