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


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.