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


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

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


как насчет использования split ("/ n")?
— jle


Думаю, было бы лучше закрыть и файл
— Павел Пражак

Ответы:


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, опубликованный за несколько лет до этого ...
— Мартино


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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.