Найкращий метод для читання файлів із роздільником нового рядка та відкидання нових рядків?


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()

Ця відповідь робить те, для чого я йшов, я впевнений, що мені потрібно додати перевірку помилок тощо, але для цієї конкретної потреби це чудово. Дякую усім за надання відповідей!
— solarce

Мені це подобається, але як закрити файл, якщо не заощадити дескриптор файлу? Або він автоматично закривається?
— Ай Джей Кеннеді,

6
У CPython кількість посилань на об'єкт файлу буде нульовою, коли він більше не використовується, і файл буде автоматично закритий. Для реалізацій виключно GC, таких як Jython та IronPython, файл може не закриватися, доки не запуститься GC, - тому така лаконічна варіація може бути не оптимальною.
— Курт Хагенлохер

2
У Mac OS X 10.7.5 з 8 ГБ оперативної пам'яті я можу прочитати файл розміром до 2047 МБ (моє визначення: 1 МБ = 1024 x 1024 байта). 2048 МБ видасть виняток 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 Using () дає вираз генератора, який не використовує стільки пам'яті, скільки використання [] (розуміння списку.)
— Джонатан Хартлі,

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") ) )

Або я можу розширити очищення за допомогою додаткових функцій, наприклад, скинути порожні рядки або пропустити рядки коментарів або що завгодно.


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 '', що мені потрібно у моєму випадку.
— Зак Янг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.