Как прочитать файл построчно в список?

2027

Как мне прочитать каждую строку файла в Python и сохранить каждую строку как элемент в списке?

Я хочу прочитать файл построчно и добавить каждую строку в конец списка.

Джули Расвик
источник

Ответы:

2174
with open(filename) 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] 
SilentGhost
источник
206
Не используйте file.readlines()в for-loop, сам файл объекта достаточно:lines = [line.rstrip('\n') for line in file]
jfs
88
В случае, если вы работаете с большими данными, использование readlines()не очень эффективно, так как это может привести к MemoryError . В этом случае лучше перебрать файл, используя for line in f:и работая с каждой lineпеременной.
DarkCygnus
7
Я проверил профиль памяти различными способами, приведенными в ответах, используя процедуру, упомянутую здесь . Использование памяти намного лучше, когда каждая строка читается из файла и обрабатывается, как предлагает @DevShark здесь . Удерживать все строки в объекте коллекции не очень хорошая идея, если память ограничена или размер файла велик. Время выполнения одинаково в обоих подходах.
Tirtha R
6
Кроме того, .rstrip()будет работать немного быстрее, если вы удаляете пробелы с концов линий.
Гринго Суаве
Oneliner:with open(filename) as f: content = [i.strip() for i in f.readlines()]
Вишал Гупта
1002

Смотрите вход и выход :

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

или с удалением символа новой строки:

with open('filename') as f:
    lines = [line.rstrip() for line in f]
Феликс Клинг
источник
12
Лучше, используйте f.read().splitlines(), который действительно удаляет новые строки
Марк
Вторая версия, с for line in open(filename)безопасным? То есть файл будет автоматически закрыт?
becko
2
Лучше всего читать файл по одной строке за раз, а не читать весь файл в память все сразу. Это плохо масштабируется с большими входными файлами. Смотрите ответ ниже Роберт.
Брэд Хейн
1
lines = [x.rstrip('\n') for x in open('data\hsf.txt','r')]Если я пишу таким образом, как я могу закрыть файл после прочтения?
Рамиса Анжум Адити
2
Да, к тому, что здесь делают другие, хотя использование open«менеджера контекста» (или какого-либо другого гарантированного способа его закрытия) не является «лучшей практикой», но на самом деле это не один из тех случаев - когда у объекта больше нет ссылок для него будет сборка мусора и закрытие файла, что должно произойти сразу после ошибки или нет, когда обработка списка завершена.
Аарон Холл
579

Это более явно, чем необходимо, но делает то, что вы хотите.

with open("file.txt") as file_in:
    lines = []
    for line in file_in:
        lines.append(line)
Роберт
источник
18
Я предпочитаю этот ответ, поскольку он не требует загрузки всего файла в память (в этом случае он все еще добавляется, arrayхотя могут быть и другие обстоятельства). Конечно, для больших файлов этот подход может смягчить проблемы.
JohannesB
1
Присоединение к массиву происходит медленно. Я не могу придумать случай использования, где это лучшее решение.
Элиас Стреле
@haccks это лучше, потому что он не загружает весь файл в память или там больше?
OrigamiEye
4
Примечание: это решение не убирает новые строки.
AMC
1
Это решение загружает весь файл в память. Я не знаю, почему люди так думают.
andrebrait
274

Это даст «массив» строк из файла.

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

openвозвращает файл, который может быть повторен. Когда вы перебираете файл, вы получаете строки из этого файла. tupleможет взять итератор и создать для вас экземпляр кортежа из предоставленного вами итератора. linesэто кортеж, созданный из строк файла.

Noctis Skytower
источник
31
@MarshallFarrier Попробуйте lines = open(filename).read().split('\n')вместо этого.
Noctis Skytower
16
он закрывает файл?
Вануан
5
@Vanuan Поскольку после запуска строки не остается никакой ссылки на файл, деструктор должен автоматически закрыть файл.
Noctis Skytower
30
@NoctisSkytower Я нахожу lines = open(filename).read().splitlines()немного чище и считаю, что он также лучше обрабатывает окончания строк DOS.
Jaynp
8
@ 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). Создание a 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
194

Если вы хотите \nвключить:

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

Если вы не хотите, чтобы \nвключены:

with open(fname) as f:
    content = f.read().splitlines()
Энеко Алонсо
источник
168

В соответствии с Методами Файловых Объектов Питона , самый простой способ преобразовать текстовый файл в list:

with open('file.txt') as f:
    my_list = list(f)

Если вам просто нужно перебрать строки текстового файла, вы можете использовать:

with open('file.txt') as f:
    for line in f:
       ...

Старый ответ:

Использование withи readlines():

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

Если вам не нужно закрывать файл, эта однострочная работа работает:

lines = open('file.txt').readlines()

Традиционный способ:

f = open('file.txt') # Open file on read mode
lines = f.read().split("\n") # Create a list containing all lines
f.close() # Close file
CONvid19
источник
150

Вы можете просто сделать следующее, как было предложено:

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 проход. Как правило, именно так будут работать универсальные парсеры.

DevShark
источник
5
Это было именно то, что мне было нужно - и спасибо за объяснение минусов. Будучи новичком в Python, удивительно понять, почему решение - это решение. Ура!
Ephexx
5
Подумай немного больше Кори. Вы действительно хотите, чтобы ваш компьютер читал каждую строку, ничего не делая с этими строками? Конечно, вы можете понять, что вам всегда нужно обрабатывать их так или иначе.
DevShark
5
Вам всегда нужно что-то делать со строками. Это может быть так же просто, как печатать строки или считать их. Нет никакого смысла в том, чтобы ваш процесс читал строки в памяти, но ничего с этим не делал.
DevShark
2
Вам всегда нужно что-то делать с ними. Я думаю, что вы пытаетесь подчеркнуть, что вы можете применить функцию ко всем сразу, а не по одному. Это действительно так иногда. Но это очень неэффективно с точки зрения памяти и не позволяет вам читать файлы, если его размер больше, чем у вашего Ram. Вот почему типичные парсеры работают так, как я описал.
DevShark
2
@PierreOcinom это правильно. Учитывая, что файл открыт в режиме только для чтения, вы не можете изменить исходный файл с кодом выше. Чтобы открыть файл для чтения и записи, используйтеopen('file_path', 'r+')
DevShark
66

Данные в список

Предположим, что у нас есть текстовый файл с нашими данными, как в следующих строках:

Содержание текстового файла:

line 1
line 2
line 3
  • Откройте cmd в том же каталоге (щелкните правой кнопкой мыши и выберите cmd или PowerShell)
  • Запустите pythonи в интерпретаторе напишите:

Скрипт Python:

>>> with open("myfile.txt", encoding="utf-8") as file:
...     x = [l.rstrip("\n") for l in file]
>>> x
['line 1','line 2','line 3']

Используя append:

x = []
with open("myfile.txt") as file:
    for l in file:
        x.append(l.strip())

Или:

>>> x = open("myfile.txt").read().splitlines()
>>> x
['line 1', 'line 2', 'line 3']

Или:

>>> x = open("myfile.txt").readlines()
>>> x
['linea 1\n', 'line 2\n', 'line 3\n']

Или:

def print_output(lines_in_textfile):
    print("lines_in_textfile =", lines_in_textfile)

y = [x.rstrip() for x in open("001.txt")]
print_output(y)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = file.read().splitlines()
    print_output(file)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = [x.rstrip("\n") for x in file]
    print_output(file)

вывод:

lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']
Giovanni G. PY
источник
1
read().splitlines()предоставляется вам Python: это просто readlines()(что, вероятно, быстрее, так как это менее расточительно).
Эрик О Лебиго,
1
@EricOLebigot из показанных примеров выглядит read().splitlines()и readlines()не выдает тот же результат. Вы уверены, что они эквивалентны?
Craq
1
Если вы используете только readlines, вам нужно использовать метод strip, чтобы избавиться от \ n в тексте, поэтому я изменил последние примеры, используя понимание списка, чтобы иметь одинаковый вывод в обоих случаях. Итак, если вы используете read (). Readlines (), у вас будет «чистый» элемент со строкой и без символа перевода строки, в противном случае вы должны сделать то, что видите в приведенном выше коде.
Джованни Г. Пи
1
Верно. Обратите внимание, что в приведенном выше коде все символы strip()должны быть rstrip("\n")или пробелы вокруг строки удаляются. Кроме того, readlines()в понимании списка нет никакого смысла : лучше просто выполнять итерации по файлу, так как он не тратит время и память, создавая промежуточный список строк.
Эрик О Лебиго
1
@EricOLebigot Готово, спасибо.
Джованни Г. Пи
43

Чтобы прочитать файл в список, вам нужно сделать три вещи:

  • Открыть файл
  • Читать файл
  • Хранить содержимое в виде списка

К счастью, Python делает это очень легко, поэтому самый короткий способ прочитать файл в список:

lst = list(open(filename))

Однако я добавлю еще несколько объяснений.

Открытие файла

Я предполагаю, что вы хотите открыть определенный файл, и вы не имеете дело непосредственно с дескриптором файла (или с дескриптором файла). Наиболее часто используемая функция для открытия файла в Python - openэто один обязательный аргумент и два необязательных в Python 2.7:

  • Имя файла
  • Режим
  • Буферизация (я проигнорирую этот аргумент в этом ответе)

Имя файла должно быть строкой, которая представляет путь к файлу . Например:

open('afile')   # opens the file named afile in the current working directory
open('adir/afile')            # relative path (relative to the current working directory)
open('C:/users/aname/afile')  # absolute path (windows)
open('/usr/local/afile')      # absolute path (linux)

Обратите внимание, что необходимо указать расширение файла. Это особенно важно для пользователей Windows, поскольку такие расширения файлов, как .txtили .doc, и т. Д. По умолчанию скрыты при просмотре в проводнике.

Второй аргумент - modeэто rпо умолчанию, что означает «только для чтения». Это именно то, что вам нужно в вашем случае.

Но если вы действительно хотите создать файл и / или записать в файл, вам понадобится другой аргумент. Есть отличный ответ, если вы хотите обзор .

Для чтения файла вы можете опустить modeили передать его явно:

open(filename)
open(filename, 'r')

Оба откроют файл в режиме только для чтения. Если вы хотите прочитать в двоичном файле в Windows, вам нужно использовать режим rb:

open(filename, 'rb')

На других платформах 'b'(двоичный режим) просто игнорируется.


Теперь, когда я показал, как с openфайлом, давайте поговорим о том факте, что вам всегда это нужно closeснова. В противном случае он будет хранить открытый дескриптор файла до тех пор, пока не завершится процесс (или Python не обработает дескриптор файла).

Пока вы можете использовать:

f = open(filename)
# ... do stuff with f
f.close()

Это не удастся закрыть файл, когда что-то между openи closeвыдает исключение. Вы можете избежать этого, используя tryи finally:

f = open(filename)
# nothing in between!
try:
    # do stuff with f
finally:
    f.close()

Однако Python предоставляет контекстные менеджеры, которые имеют более симпатичный синтаксис (но openон почти идентичен тому, что tryи finallyвыше):

with open(filename) as f:
    # do stuff with f
# The file is always closed after the with-scope ends.

Последний подход - рекомендуемый подход для открытия файла в Python!

Чтение файла

Хорошо, вы открыли файл, теперь как его прочитать?

openФункция возвращает fileобъект , и он поддерживает протокол итерации питонов. Каждая итерация даст вам строку:

with open(filename) as f:
    for line in f:
        print(line)

Это напечатает каждую строку файла. Однако обратите внимание, что каждая строка будет содержать символ новой строки \nв конце (возможно, вы захотите проверить, построен ли ваш Python с поддержкой универсальной новой строки - в противном случае вы могли бы также использовать \r\nв Windows или \rна Mac новые строки). Если вы не хотите, вы можете просто удалить последний символ (или два последних символа в Windows):

with open(filename) as f:
    for line in f:
        print(line[:-1])

Но последняя строка не обязательно имеет завершающий символ новой строки, поэтому не стоит ее использовать. Можно проверить, заканчивается ли он завершающим символом новой строки, и, если это так, удалить его:

with open(filename) as f:
    for line in f:
        if line.endswith('\n'):
            line = line[:-1]
        print(line)

Но вы можете просто удалить все пробелы (включая \nсимвол) в конце строки , это также удалит все другие конечные пробелы, поэтому вы должны быть осторожны, если они важны:

with open(filename) as f:
    for line in f:
        print(f.rstrip())

Однако, если строки заканчиваются \r\n(Windows, "новые строки"), .rstrip()это также позаботится о \r!

Хранить содержимое в виде списка

Теперь, когда вы знаете, как открыть файл и прочитать его, пришло время сохранить содержимое в списке. Самый простой вариант - использовать listфункцию:

with open(filename) as f:
    lst = list(f)

В случае, если вы хотите убрать завершающие символы новой строки, вы можете использовать вместо этого понимание списка:

with open(filename) as f:
    lst = [line.rstrip() for line in f]

Или даже проще: .readlines()метод fileобъекта по умолчанию возвращает listстроку:

with open(filename) as f:
    lst = f.readlines()

Это также будет включать в себя завершающие символы новой строки, если вы не хотите их использовать, я бы порекомендовал [line.rstrip() for line in f]подход, потому что он избегает хранения двух списков, содержащих все строки в памяти.

Есть дополнительная опция для получения желаемого результата, однако она довольно «неоптимальная»: readполный файл в строке, а затем разделенный на новые строки:

with open(filename) as f:
    lst = f.read().split('\n')

или:

with open(filename) as f:
    lst = f.read().splitlines()

Они позаботятся о конце новой строки, потому что splitперсонаж не включен. Однако они не идеальны, потому что вы сохраняете файл как строку и как список строк в памяти!

Резюме

  • Используйте with open(...) as fпри открытии файлов, потому что вам не нужно заботиться о закрытии файла самостоятельно, и он закрывает файл, даже если происходит какое-то исключение.
  • fileобъекты поддерживают протокол итерации, поэтому чтение файла построчно так же просто, как и for line in the_file_object:.
  • Всегда просматривайте документацию для доступных функций / классов. Большую часть времени идеально подходит для этой задачи или, по крайней мере, один или два хороших. Очевидный выбор в этом случае будет, readlines()но если вы хотите обработать строки перед сохранением их в списке, я бы порекомендовал простое понимание списка.
MSeifert
источник
Последний подход - рекомендуемый подход для открытия файла в Python! Почему это последний, тогда? Разве подавляющее большинство людей не посмотрят на первые несколько строк ответа, прежде чем двигаться дальше?
AMC
@AMC Я не особо задумывался над этим, когда писал ответ. Как вы думаете, я должен поставить его в верхней части ответа?
MSeifert
Это может быть лучше, да. Я также только что заметил, что вы упоминаете Python 2, так что это тоже можно обновить.
AMC
Ах вопрос был изначально помечен Python-2.x. Возможно, имеет смысл обновить его более широко. Я посмотрю, приду ли я к этому в следующий раз. Спасибо за ваши предложения. Очень признателен!
MSeifert
42

Чистый и Pythonic способ чтения строк файла в список


Прежде всего, вы должны сосредоточиться на том, чтобы открыть свой файл и прочитать его содержимое эффективным и питонным способом. Вот пример того, как я лично НЕ предпочитаю:

infile = open('my_file.txt', 'r')  # Open the file for reading.

data = infile.read()  # Read the contents of the file.

infile.close()  # Close the file since we're done using it.

Вместо этого я предпочитаю нижеприведенный метод открытия файлов для чтения и записи, поскольку он очень чистый и не требует дополнительного шага закрытия файла после того, как вы его закончили. В приведенном ниже утверждении мы открываем файл для чтения и присваиваем его переменной infile. Как только код в этом операторе закончится, файл будет автоматически закрыт.

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

Теперь нам нужно сосредоточиться на переносе этих данных в список Python, потому что они итеративны, эффективны и гибки. В вашем случае желаемая цель состоит в том, чтобы перенести каждую строку текстового файла в отдельный элемент. Для этого мы будем использовать метод splitlines () следующим образом:

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

Конечный продукт:

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

Тестирование нашего кода:

  • Содержание текстового файла:
     A fost odatã ca-n povesti,
     A fost ca niciodatã,
     Din rude mãri împãrãtesti,
     O prea frumoasã fatã.
  • Распечатайте заявления для тестирования:
    print my_list  # Print the list.

    # Print each line in the list.
    for line in my_list:
        print line

    # Print the fourth element in this list.
    print my_list[3]
  • Вывод (другой вид из-за символов юникода):
     ['A fost odat\xc3\xa3 ca-n povesti,', 'A fost ca niciodat\xc3\xa3,',
     'Din rude m\xc3\xa3ri \xc3\xaemp\xc3\xa3r\xc3\xa3testi,', 'O prea
     frumoas\xc3\xa3 fat\xc3\xa3.']

     A fost odatã ca-n povesti, A fost ca niciodatã, Din rude mãri
     împãrãtesti, O prea frumoasã fatã.

     O prea frumoasã fatã.
Джонни
источник
30

Представленный в Python 3.4, pathlibимеет действительно удобный метод для чтения текста из файлов, а именно:

from pathlib import Path
p = Path('my_text_file')
lines = p.read_text().splitlines()

(Этот splitlinesвызов превращает его из строки, содержащей все содержимое файла, в список строк в файле).

pathlibимеет много удобных удобств. read_textэто красиво и кратко, и вам не нужно беспокоиться об открытии и закрытии файла. Если все, что вам нужно сделать с файлом, это прочитать все сразу, это хороший выбор.

LangeHaare
источник
29

Вот еще один вариант, используя списки в файлах;

lines = [line.rstrip() for line in open('file.txt')]

Это должно быть более эффективным способом, так как большая часть работы выполняется внутри интерпретатора Python.

user1833244
источник
10
rstrip()потенциально удаляет все конечные пробелы, а не только \n; использовать .rstrip('\n').
mklement0
Это также не гарантирует, что файл будет закрыт после прочтения во всех реализациях Python (хотя в CPython, основной реализации Python, это будет).
Марк Амери
1
Это должно быть более эффективным способом, так как большая часть работы выполняется внутри интерпретатора Python. Что это обозначает?
AMC
28
f = open("your_file.txt",'r')
out = f.readlines() # will append in the list out

Теперь переменная out - это список (массив) того, что вы хотите. Вы можете сделать:

for line in out:
    print (line)

Или:

for line in f:
    print (line)

Вы получите те же результаты.

moldovean
источник
27

Чтение и запись текстовых файлов с помощью Python 2 и Python 3; это работает с Unicode

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Define data
lines = ['     A first string  ',
         'A Unicode sample: €',
         'German: äöüß']

# Write text file
with open('file.txt', 'w') as fp:
    fp.write('\n'.join(lines))

# Read text file
with open('file.txt', 'r') as fp:
    read_lines = fp.readlines()
    read_lines = [line.rstrip('\n') for line in read_lines]

print(lines == read_lines)

На что обратить внимание:

  • withэто так называемый контекстный менеджер . Это гарантирует, что открытый файл снова закрыт.
  • Все решения здесь, которые просто принимают .strip()или .rstrip()не смогут воспроизвести, linesпоскольку они также удаляют пустое пространство.

Общие окончания файлов

.txt

Более продвинутая запись / чтение файлов

Для вашего приложения может быть важно следующее:

  • Поддержка другими языками программирования
  • Чтение / запись производительности
  • Компактность (размер файла)

Смотрите также: Сравнение форматов сериализации данных

Если вы предпочитаете создавать конфигурационные файлы, вы можете прочитать мою короткую статью Конфигурационные файлы на Python .

Мартин Тома
источник
26

Другой вариант numpy.genfromtxt, например:

import numpy as np
data = np.genfromtxt("yourfile.dat",delimiter="\n")

Это создаст dataмассив NumPy с таким количеством строк в вашем файле.

atomh33ls
источник
25

Если вы хотите прочитать файл из командной строки или из стандартного ввода, вы также можете использовать fileinputмодуль:

# reader.py
import fileinput

content = []
for line in fileinput.input():
    content.append(line.strip())

fileinput.close()

Передайте файлы ему так:

$ python reader.py textfile.txt 

Подробнее читайте здесь: http://docs.python.org/2/library/fileinput.html

oliland
источник
20

Самый простой способ сделать это

Простой способ состоит в том, чтобы:

  1. Прочитать весь файл как строку
  2. Разделить строку строка за строкой

В одной строке это даст:

lines = open('C:/path/file.txt').read().splitlines()

Тем не менее, это довольно неэффективный способ, поскольку он будет хранить 2 версии контента в памяти (вероятно, не является большой проблемой для небольших файлов, но все же). [Спасибо Марк Эмери].

Есть 2 простых способа:

  1. Использование файла в качестве итератора
lines = list(open('C:/path/file.txt'))
# ... or if you want to have a list without EOL characters
lines = [l.rstrip() for l in open('C:/path/file.txt')]
  1. Если вы используете Python 3.4 или выше, лучше использовать pathlibдля создания пути для вашего файла, который вы могли бы использовать для других операций в вашей программе:
from pathlib import Path
file_path = Path("C:/path/file.txt") 
lines = file_path.read_text().split_lines()
# ... or ... 
lines = [l.rstrip() for l in file_path.open()]
Жан-Франсуа Т.
источник
Это плохой подход. С одной стороны, звонить .read().splitlines()не проще, чем просто звонить .readlines(). С другой стороны, это неэффективно для памяти; вам не нужно хранить две версии содержимого файла (одну возвращаемую строку .read()и список возвращаемых строк splitlines()) одновременно в памяти.
Марк Амери
@MarkAmery Правда. Спасибо за выделение этого. Я обновил свой ответ.
Жан-Франсуа Т.
14

Просто используйте функции splitlines (). Вот пример.

inp = "file.txt"
data = open(inp)
dat = data.read()
lst = dat.splitlines()
print lst
# print(lst) # for python 3

В выводе у вас будет список строк.

Абдулла Билал
источник
Недостаточно памяти по сравнению с использованием .readlines(). Это помещает две копии содержимого файла в память одновременно (одну как одну огромную строку, одну как список строк).
Марк Амери
11

Если вы хотите столкнуться с очень большим / огромным файлом и хотите читать быстрее (представьте, что вы участвуете в конкурсе кодирования Topcoder / Hackerrank), вы можете за один раз прочитать значительно больший кусок строк в буфере памяти, а не просто итерации построчно на уровне файла.

buffersize = 2**16
with open(path) as f: 
    while True:
        lines_buffer = f.readlines(buffersize)
        if not lines_buffer:
            break
        for line in lines_buffer:
            process(line)
pambda
источник
что делает процесс (строка)? Я получаю ошибку, что не определена такая переменная. Я думаю, что-то требует импорта, и я попытался импортировать многопроцессорность. Процесс, но это не так, я думаю. Не могли бы вы уточнить? Спасибо
Newskooler
1
process(line)это функция, которую вам нужно реализовать для обработки данных. например, вместо этой строки, если вы используете print(line), она будет печатать каждую строку из lines_buffer.
Ханал
f.readlines (buffersize) возвращает неизменный буфер. если вы хотите напрямую читать в свой буфер, вам нужно использовать функцию readinto (). Я буду намного быстрее.
Дэвид Дехган
7

Простейшие способы сделать это с некоторыми дополнительными преимуществами:

lines = list(open('filename'))

или

lines = tuple(open('filename'))

или

lines = set(open('filename'))

В случае с set, мы должны помнить, что у нас не сохранен порядок строк и избавиться от дублированных строк.

Ниже я добавил важное дополнение от @MarkAmery :

Поскольку вы не вызываете .closeобъект файла и не используете withоператор, в некоторых реализациях Python файл может не закрыться после чтения, и ваш процесс утечет дескриптором открытого файла .

В CPython (обычной реализации Python, которую использует большинство людей), это не проблема, поскольку объект file будет сразу же очищен от мусора, и это закроет файл, но, тем не менее, обычно считается, что рекомендуется делать что-то вроде :

with open('filename') as f: lines = list(f) 

чтобы обеспечить закрытие файла независимо от того, какую реализацию Python вы используете.

simhumileco
источник
1
Поскольку вы не вызываете .closeобъект файла и не используете withоператор, в некоторых реализациях Python файл может не закрыться после чтения, и ваш процесс утечет дескриптором открытого файла. В CPython (обычная реализация Python, которую использует большинство людей), это не проблема, поскольку объект file будет сразу же очищен от мусора, и это закроет файл, но, тем не менее, обычно считается, что рекомендуется делать что-то вроде, with open('filename') as f: lines = list(f)чтобы гарантировать, что файл закрывается независимо от того, какую реализацию Python вы используете.
Марк Амери
Спасибо за ваш замечательный комментарий @MarkAmery! Я очень ценю это.
simhumileco
1
@simhumileco Почему лучшее (правильное) решение длятся?
AMC
@AMC, потому что сначала я хотел показать простейшие способы и последовательность рассуждений.
simhumileco
Кроме того, я надеюсь, что мой ответ сделан таким, чтобы он был коротким и легким для чтения.
simhumileco
4

Использовать этот:

import pandas as pd
data = pd.read_csv(filename) # You can also add parameters such as header, sep, etc.
array = data.values

dataтип данных и использует значения для получения ndarray. Вы также можете получить список с помощью array.tolist().

Нуль
источник
pandas.read_csv()для чтения данных CSV , как это уместно здесь?
AMC
4

План и Резюме

С помощью filenameобработки файла из Path(filename)объекта или непосредственно с помощью open(filename) as fвыполните одно из следующих действий:

  • list(fileinput.input(filename))
  • используя with path.open() as f, позвонитеf.readlines()
  • list(f)
  • path.read_text().splitlines()
  • path.read_text().splitlines(keepends=True)
  • перебирать fileinput.inputили fи list.appendкаждую строку по одной за раз
  • перейти fк связанному list.extendметоду
  • использовать fв понимании списка

Я объясню вариант использования для каждого ниже.

В Python, как мне прочитать файл построчно?

Это отличный вопрос. Во-первых, давайте создадим несколько примеров данных:

from pathlib import Path
Path('filename').write_text('foo\nbar\nbaz')

Файловые объекты являются ленивыми итераторами, так что просто повторяйте их.

filename = 'filename'
with open(filename) as f:
    for line in f:
        line # do something with the line

В качестве альтернативы, если у вас есть несколько файлов, используйте fileinput.inputдругой ленивый итератор. Всего одним файлом:

import fileinput

for line in fileinput.input(filename): 
    line # process the line

или для нескольких файлов передайте ему список имен файлов:

for line in fileinput.input([filename]*2): 
    line # process the line

Снова fи fileinput.inputвыше оба являются / возвращают ленивые итераторы. Вы можете использовать итератор только один раз, поэтому, чтобы обеспечить функциональный код, избегая многословия, я буду использовать немного более краткий, fileinput.input(filename)где уместно отсюда.

В Python, как мне прочитать файл построчно в список?

Ах, но вы хотите это в списке по какой-то причине? Я бы избежал этого, если это возможно. Но если вы настаиваете ... просто передать результат fileinput.input(filename)в list:

list(fileinput.input(filename))

Другой прямой ответ - вызов f.readlines, который возвращает содержимое файла (до необязательного hintколичества символов, чтобы вы могли разбить его на несколько списков таким образом).

Вы можете получить к этому файлу объект двумя способами. Один из способов - передать имя файла openвстроенному:

filename = 'filename'

with open(filename) as f:
    f.readlines()

или используя новый объект Path из pathlibмодуля (который я очень полюбил и буду использовать с этого момента ):

from pathlib import Path

path = Path(filename)

with path.open() as f:
    f.readlines()

list также будет использовать файловый итератор и возвращать список - довольно прямой метод:

with path.open() as f:
    list(f)

Если вы не возражаете прочесть весь текст в память как одну строку перед тем, как разбивать ее, вы можете сделать это как одну строку с Pathобъектом и splitlines()строковым методом. По умолчанию splitlinesудаляет символы новой строки:

path.read_text().splitlines()

Если вы хотите сохранить переводы строк, передайте keepends=True:

path.read_text().splitlines(keepends=True)

Я хочу прочитать файл построчно и добавить каждую строку в конец списка.

Теперь просить это немного глупо, учитывая, что мы легко продемонстрировали конечный результат несколькими методами. Но вам может понадобиться отфильтровать или обработать строки при составлении списка, поэтому давайте рассмотрим этот запрос.

Использование list.appendпозволит вам фильтровать или работать с каждой строкой, прежде чем добавить ее:

line_list = []
for line in fileinput.input(filename):
    line_list.append(line)

line_list

Использование list.extendбудет немного более прямым и, возможно, полезным, если у вас есть существующий список:

line_list = []
line_list.extend(fileinput.input(filename))
line_list

Или, более идиотски, мы могли бы вместо этого использовать понимание списка, и отображать и фильтровать его, если это желательно:

[line for line in fileinput.input(filename)]

Или, еще более прямо, чтобы замкнуть круг, просто передайте его списку, чтобы создать новый список напрямую, не работая со строками:

list(fileinput.input(filename))

Вывод

Вы видели много способов получить строки из файла в список, но я бы порекомендовал вам избегать материализации больших объемов данных в список и вместо этого использовать ленивую итерацию Python для обработки данных, если это возможно.

То есть предпочитаю fileinput.inputили with path.open() as f.

Аарон Холл
источник
4

В случае, если в документе также есть пустые строки, я хотел бы прочитать содержимое и пропустить его, filterчтобы предотвратить пустые строковые элементы.

with open(myFile, "r") as f:
    excludeFileContent = list(filter(None, f.read().splitlines()))
jeanggi90
источник
1
Это не пифонично, будьте осторожны.
AMC
3

Вы также можете использовать команду loadtxt в NumPy. Это проверяет меньше условий, чем genfromtxt, так что это может быть быстрее.

import numpy
data = numpy.loadtxt(filename, delimiter="\n")
asampat3090
источник
2

Мне нравится использовать следующее. Чтение строк сразу.

contents = []
for line in open(filepath, 'r').readlines():
    contents.append(line.strip())

Или используя понимание списка:

contents = [line.strip() for line in open(filepath, 'r').readlines()]
Даниил
источник
2
Нет необходимости readlines(), что даже влечет за собой потерю памяти. Вы можете просто удалить его, поскольку итерации по (текстовому) файлу дают каждую строку по очереди.
Эрик О Лебиго,
2
Вы должны использовать withоператор, чтобы открыть (и неявно закрыть) файл.
Аран-Фей
2

Я бы попробовал один из следующих методов. Файл примера, который я использую, имеет имя dummy.txt. Вы можете найти файл здесь . Я предполагаю, что файл находится в том же каталоге, что и код (вы можете изменить, fpathчтобы включить правильное имя файла и путь к папке.)

В обоих приведенных ниже примерах список, который вы хотите получить lst.

1.> Первый способ :

fpath = 'dummy.txt'
with open(fpath, "r") as f: lst = [line.rstrip('\n \t') for line in f]

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

2.> Во втором методе можно использовать модуль csv.reader из стандартной библиотеки Python :

import csv
fpath = 'dummy.txt'
with open(fpath) as csv_file:
    csv_reader = csv.reader(csv_file, delimiter='   ')
    lst = [row[0] for row in csv_reader] 

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

Вы можете использовать любой из двух методов. Время, затрачиваемое на создание, lstпрактически одинаково в двух методах.

Сиддхарт Сатпатия
источник
1
В чем преимущество второго подхода? Зачем вызывать дополнительную библиотеку, которая добавляет в крайних случаях (разделитель и кавычки)?
Чарли Хардинг
Для чего delimiter=' 'аргумент?
AMC
2

Вот вспомогательный класс библиотеки Python (3), который я использую для упрощения файлового ввода-вывода:

import os

# handle files using a callback method, prevents repetition
def _FileIO__file_handler(file_path, mode, callback = lambda f: None):
  f = open(file_path, mode)
  try:
    return callback(f)
  except Exception as e:
    raise IOError("Failed to %s file" % ["write to", "read from"][mode.lower() in "r rb r+".split(" ")])
  finally:
    f.close()


class FileIO:
  # return the contents of a file
  def read(file_path, mode = "r"):
    return __file_handler(file_path, mode, lambda rf: rf.read())

  # get the lines of a file
  def lines(file_path, mode = "r", filter_fn = lambda line: len(line) > 0):
    return [line for line in FileIO.read(file_path, mode).strip().split("\n") if filter_fn(line)]

  # create or update a file (NOTE: can also be used to replace a file's original content)
  def write(file_path, new_content, mode = "w"):
    return __file_handler(file_path, mode, lambda wf: wf.write(new_content))

  # delete a file (if it exists)
  def delete(file_path):
    return os.remove() if os.path.isfile(file_path) else None

Затем вы бы использовали FileIO.linesфункцию, например так:

file_ext_lines = FileIO.lines("./path/to/file.ext"):
for i, line in enumerate(file_ext_lines):
  print("Line {}: {}".format(i + 1, line))

Помните, что параметры mode( "r"по умолчанию) и filter_fn(проверяет наличие пустых строк по умолчанию) являются необязательными.

Вы можете даже удалить методы read, writeи deleteи просто оставить FileIO.lines, или даже превратить его в отдельный вызываемый метод read_lines.

LogicalBranch
источник
Действительно lines = FileIO.lines(path)ли это проще, чем with open(path) as f: lines = f.readlines()оправдать существование этого помощника? Вы экономите 17 символов на вызов. (И в большинстве случаев по соображениям производительности и памяти вы захотите зацикливаться на файловом объекте напрямую, а не в любом случае читать его строки в списке, так что вам даже не захочется использовать это часто!) часто фанат создания небольших утилитарных функций, но мне кажется, что это просто ненужно создавать новый способ написать что-то, что уже коротко и легко с помощью стандартной библиотеки.
Марк Амери
В дополнение к тому, что @MarkAmery сказал, зачем использовать для этого класс?
AMC
1

Версия командной строки

#!/bin/python3
import os
import sys
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
filename = dname + sys.argv[1]
arr = open(filename).read().split("\n") 
print(arr)

Бежать с:

python3 somefile.py input_file_name.txt
jasonleonhard
источник