Питання У Python, як я читаю файли по черзі в список?


Як я читаю кожен рядок файлу в Python і зберігаю кожну рядок як елемент у списку?

Я хочу прочитати рядок файлів за рядком і додати кожну лінію до кінця списку.


1703
2017-07-18 22:25


походження




Відповіді:


with open(fname) as f:
    content = f.readlines()
# you may also want to remove whitespace characters like `\n` at the end of each line
content = [x.strip() for x in content] 

1659
2017-07-18 22:28



Не використовуйте file.readlines() в for-олоп, сам файл-об'єкт досить: lines = [line.rstrip('\n') for line in file] - jfs
У випадку, коли ви працюєте з використанням великих даних readlines() це не дуже ефективно, як це може призвести MemoryError. У цьому випадку краще ітератувати файл за допомогою for line in f: і працюючи з кожним line змінна - DarkCygnus
Я перевірив профіль пам'яті різних способів, наведених у відповідях, використовуючи зазначену процедуру тут. Використання пам'яті набагато краще, коли кожен рядок читається з файлу та обробляється, як це пропонується @DevShark тут. Утримувати всі лінії в об'єкті збирання є ні Хороша ідея, якщо пам'ять є обмеженням або великий файл. Час виконання аналогічний в обох підходах. - Tirtha R
Крім того, .rstrip() працюватиме трохи швидше, якщо ви стираєте пробіли від кінців рядків. - Gringo Suave


Побачити Вхідний і вхідний:

with open('filename') as f:
    lines = f.readlines()

або зі зняттям символу нового рядка:

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

Примітка редактора: оригінальна команда видалення пробілів у відповідь line.strip(), як це передбачав коментар Януса Троулзена, буде видалено все провідне та заднє пробіл, а не тільки пробій \n.


781
2017-07-18 22:28



якщо ви хочете виключити нову лінію: lines = (line.rstrip('\n') for line in open(filename)) - Janus Troelsen
Для списку це має бути lines = [line.rstrip('\n') for line in open(filename)] - Lazik
Чи не буде другий варіант залишити файл відкритим (оскільки він не захищений контекстом самостійно)? - yo'
@yo "Це робить, але більшість людей не піклуються про це в невеликих програмах. Маленькі програми не завдають шкоди, тому що витік об'єкта файлу - це сміття, але це не є гарною звичкою для цього. - Martin Ueding
Безпечніше: with open('filename') as f: lines = [line.rstrip('\n') for line in f] - becko


Це більш чітко, ніж потрібно, але робить те, що ви хочете.

with open("file.txt", "r") as ins:
    array = []
    for line in ins:
        array.append(line)

369
2017-07-18 22:27



Це пряма відповідь на питання - Joop


Це дасть "масив" рядків з файлу.

lines = tuple(open(filename, 'r'))

206
2017-07-18 22:27



open повертає файл, який може бути повторений. Коли ви переглядаєте файл, ви отримуєте рядки з цього файлу. tuple може взяти ітератор та інстанція екземпляру кортежу для вас з ітератора, який ви його даєте. lines це кортеж, створений з рядків файлу. - Noctis Skytower
@MarshallFarrier Спробуйте lines = open(filename).read().split('\n') замість цього. - Noctis Skytower
він закриває файл? - Vanuan
@NoctisSkytower я знаходжу lines = open(filename).read().splitlines() трохи чистіше, і я вважаю, що він також обробляє закінчення ліній DOS краще. - jaynp
@ mklement0 Припускаючи файл з 1000 рядків, a list займає на 13,22% більше місця, ніж a tuple. Результати приходять з from sys import getsizeof as g; i = [None] * 1000; round((g(list(i)) / g(tuple(i)) - 1) * 100, 2). Створення а tuple займає на 4.17% більше часу, ніж створення list (зі стандартним відхиленням 0,16%). Результати приходять із запуску from timeit import timeit as t; round((t('tuple(i)', 'i = [None] * 1000') / t('list(i)', 'i = [None] * 1000') - 1) * 100, 2) 30 разів Моє рішення сприяє просторі над швидкістю, коли необхідність змінності невідома. - Noctis Skytower


Якщо ви хочете \n включені:

with open(fname) as f:
    content = f.readlines()

Якщо ти не хочеш \n включені:

with open(fname) as f:
    content = f.read().splitlines()

150
2018-03-02 04:22





Ви можете просто зробити наступне, як було запропоновано:

with open('/your/path/file') as f:
    my_lines = f.readlines()

Зауважте, що цей підхід має 2 недоліки:

1) Ви зберігаєте всі рядки в пам'яті. У загальному випадку це дуже погана ідея. Файл може бути дуже великим, і ви можете запустити пам'ять. Навіть якщо це не велика, це просто марна пам'ять.

2) Це не дозволяє обробляти кожну лінію при їх читанні. Отже, якщо ви обробляєте свої лінії після цього, це не є ефективним (вимагає не двох, а двох пас).

Кращий підхід до загальної ситуації полягає в наступному:

with open('/your/path/file') as f:
    for line in f:
        process(line)

Де ви визначаєте функцію процесу так, як хочете. Наприклад:

def process(line):
    if 'save the world' in line.lower():
         superman.save_the_world()

(Реалізація проекту Superman клас залишається як вправ для вас).

Це буде добре працювати для будь-якого розміру файлу, і ви пройдете через свій файл всього за 1 пропуск. Як правило, це буде так, як працюють загальні аналізатори.


93
2018-02-25 09:13



Це було саме те, що мені потрібно було - і дякую, що пояснив недоліки. Як новачок в Python, чудово розуміти, чому рішення є рішенням. Ура! - Ephexx
Подумайте трохи більше Корі. Чи дійсно ви хочете, щоб ваш комп'ютер читав кожен рядок, ніколи не робивши нічого з цими лініями? Звичайно, ви можете усвідомити, що вам завжди потрібно їх обробляти так чи інакше. - DevShark
Вам завжди потрібно щось робити з лініями. Це може бути настільки ж просто, як друк ліній або їх підрахунок. Немає сенсу, щоб ваш процес читав рядки в пам'яті, але не робив нічого з ним. - DevShark
Вам завжди потрібно щось робити з ними. Я думаю, що те, що ви намагаєтесь зробити, - це те, що ви можете застосувати функцію для всіх з них одночасно, а не по одному. І це дійсно є випадком. Але це дуже неефективно з точки зору пам'яті, і це не дозволяє вам читати файли, якщо його відстань більше, ніж ваш Ram. Ось чому типові загальні аналізатори працюють так, як я описав. - DevShark
@PierreOcinom це правильно. Оскільки файл відкритий у режимі лише читання, ви не змогли змінити вихідний файл за допомогою наведеного вище коду. Щоб відкрити файл як для читання, так і для запису, скористайтеся open('file_path', 'r+') - DevShark


Якщо ви не зацікавлені в закритті файлу, цей один-вкладиш працює:

lines = open('file.txt').read().split("\n")

The традиційний шлях:

fp = open('file.txt') # Open file on read mode
lines = fp.read().split("\n") # Create a list containing all lines
fp.close() # Close file

Використовуючи with (рекомендовано):

with open('file.txt') as fp:
    lines = fp.read().split("\n")

61
2018-04-20 05:53



У деяких випадках це може бути добре, але це не закриває файл навіть після завершення циклу - stackoverflow.com/a/1832589/232593 - Merlyn Morgan-Graham
The with блок блокує файл автоматично. Не потрібно для фіналу fp.close() в останньому прикладі. Побачити: repl.it/IMeA/0 - Merlyn Morgan-Graham
Завжди турбуйтеся про закриття файлу! Будь хорошим ресурсом громадянина! - Nick


Це має інкапсулювати відкриту команду.

array = []
with open("file.txt", "r") as f:
  for line in f:
    array.append(line)

38
2017-10-28 15:40



f.readlines () робить те ж саме. Не треба додавати до порожнього списку. - Corey Goldberg
Ти правий. Це дає уявлення про рішення, якщо ви хочете щось зробити, поки ви читаєте в рядках. Подібно деяким перетворенням смуги / регулярного виразу. - cevaris