Python прочитать файл построчно в массив

Обновлено: 05.07.2024

  • Вступление
  • Базовый файл IO в Python
  • Чтение Строка за строкой
  • Пример Приложения
  • Вывод

Вступление

Однако что вы делаете, когда файл, который вы пытаетесь использовать, довольно велик? Что делать, если файл содержит несколько ГБ данных или больше? Опять же, это был еще один частый аспект моей карьеры программиста, который в основном проводился в биотехнологическом секторе, где часто встречаются файлы размером 1 ТБ+.

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

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

Базовый файл IO в Python

Будучи отличным языком программирования общего назначения, Python имеет ряд очень полезных функций ввода-вывода файлов в своей стандартной библиотеке встроенных функций и модулей. Встроенная функция open () -это то, что вы используете для открытия объекта file для чтения или записи.

r Открыт для чтения обычного текста
w Открыт для записи обычного текста
a Откройте существующий файл для добавления обычного текста
rb Открыт для чтения двоичных данных
всемирный банк Открыт для записи двоичных данных

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

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

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

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

Чтение Строка за строкой

Теперь давайте перейдем к фактическому чтению в файле. Объект file, возвращаемый из open () , имеет три общих явных метода ( read , readline и readlines ) для чтения данных и еще один неявный способ.

Метод read будет считывать все данные в одну текстовую строку. Это полезно для небольших файлов, где вы хотели бы сделать текстовую манипуляцию со всем файлом или что-то еще, что вам подходит. Тогда есть readline , который является одним из полезных способов чтения только в отдельных строках инкрементных сумм за один раз и возврата их в виде строк. Последний явный метод, readlines , прочитает все строки файла и вернет их в виде списка строк.

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

Ниже показана одна реализация для чтения текстового файла по одной строке за раз, которая выполняется с помощью метода readline () .

В readline.py вы найдете следующий код. В терминале, если вы запустите $ python readline.py вы можете увидеть результат чтения всех строк Илиады, а также их номера строк.

Приведенный выше фрагмент кода открывает файловый объект , хранящийся в виде переменной с именем fp , затем читает строку за раз, вызывая readline на этом файловом объекте итеративно в цикле while и выводит его на консоль.

Запустив этот код, вы должны увидеть что-то вроде следующего:

Хотя это совершенно нормально, есть один последний способ, о котором я мимолетно упоминал ранее, который менее явен, но немного более элегантен, и который я очень предпочитаю. Этот последний способ чтения файла строка за строкой включает в себя итерацию по файловому объекту в цикле for , присваивая каждой строке специальную переменную с именем line . Приведенный выше фрагмент кода может быть воспроизведен в следующем коде, который можно найти в скрипте Python forlinein.py:

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

Пример Приложения

Приведенный выше код представляет собой скрипт python командной строки, который ожидает путь к файлу, переданный в качестве аргумента. Скрипт использует модуль os , чтобы убедиться, что переданный путь к файлу является файлом, существующим на диске. Если путь существует, то каждая строка файла считывается и передается функции с именем record_word_cnt в виде списка строк, разделенных пробелами между словами, а также словаря с именем bag_of_words . Функция record_word_cnt подсчитывает каждый экземпляр каждого слова и записывает его в словарь bag_of_words .

После того как все строки файла прочитаны и записаны в словарь bag_of_words , вызывается последний вызов функции order_bag_of_words , которая возвращает список кортежей в формате (word, word count) , отсортированных по количеству слов. Возвращаемый список кортежей используется для печати наиболее часто встречающихся 10 слов.

Вывод

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

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

Когда я только начинал изучать Python, главным помощником в работе для меня, как наверное и для большинства программистов, был Stack Overflow. Я почерпнул оттуда много полезной информации, в том числе и о работе с файлами. Однако даже такая тривиальная задача, как оказалось, имеет несколько различных решений, отличающихся друг от друга простотой реализации и скоростью работы.

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

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

  • построчное считывание с разбиением и преобразованием типов
  • использование библиотек, которые средствами других языков (например, C/C++) считывают файл и передают полученные данные интерпретатору Python

Самый популярный и простой вариант. Заключается в построчном чтении с разбиением полученной строки на блоки, которые затем преобразуются к необходимому типу данных (в данном случае float) и добавляются к заранее созданному списку.

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

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

Если данные записаны в виде матрицы с постоянными разделителями, то выполнить их чтение можно при помощи модуля CSV Reader, указав в качестве параметра значение разделителя.

Библиотека Numpy предоставляет широкий набор модулей и функций для обработки числовых данных, в том числе и для чтения массивов из файлов. Одна из реализаций возможна с помощью функции loadtxt, результат работы которой будет записан в numpy.array.

Данный способ не сильно отличается от предыдущего, за исключением того, что genfromtxt предоставляет более широкий набор входных параметров: указание различных типов данных для каждого из столбцов, передача ключей для создания ассоциативного массива и так далее.

Для тестирования скорости чтения числовых данных были сгенерированы 7 тестовых файлов, содержащих 5 столбцов и 10, 100, 1 000, 10 000, 100 000, 1 000 000 и 10 000 000 строк случайных чисел формата float. Размер самого большого файла составил 742 Мб.

Для измерения времени работы программы использовалась функция time. Существует мнение, что измерять с её помощью время работы некорректно. Однако в данном случае меня интересовало работа с большими объемами данных, когда время работы программы составляло несколько десятков секунд. В таком случае отклонение в полсекунды вносило погрешность менее 1%.

Fortran

Несмотря на то, что Fortran считается устаревшим языком, он все еще очень популярен в научном программировании благодаря простоте написания кода, скорости обмена данных и обширном количестве библиотек, созданных за последние полвека.

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

Дискуссии о том, что лучше: Fortran или C++ ведутся уже давно, даже среди авторов EasyCoding этот спор возникал несколько раз, поэтому мне было еще интересней протестировать чтение матриц на данном языке.

В ходе эксперимента были протестированы 7 программ на языке Python и по одной на Fortran и C++, код которых представлен выше. Запуск программ осуществлялся на компьютере с Intel Core i5 2.7 GHz и 8 Гб оперативной памяти.

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

GNU Fortran (GCC) 6.1.0

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

Число строк Способ
1 2 3 4 5 6 7 Fortran C++
10 0.048 0.048 0.045 0.044 0.173 0.216 0.479 0.005 0.005
100 0.053 0.052 0.05 0.048 0.185 0.223 0.511 0.007 0.006
1 000 0.056 0.053 0.053 0.052 0.187 0.233 0.6 0.01 0.01
10 000 0.085 0.076 0.096 0.083 0.305 0.292 0.636 0.032 0.041
100 000 0.414 0.403 0.561 0.482 1.537 0.874 0.796 0.244 0.363
1 000 000 3.835 4.502 6.086 5.276 13.607 6.754 1.763 2.584 3.662
10 000 000 47.931 156.944 137.398 144.75 162.724 85.642 13.632 25.652 36.622

Однако при увеличении объема входных данных лучше всех себя показал метод 7 с использованием библиотеки Pandas, который даже обогнал по скорости чтения данных языки C++ и Fortran.

Также из результатов теста можно видеть, что программа на Fortran справилась с чтением данных быстрей аналога на C++, что еще раз доказывает его превосходство над самым популярным языком программирования в мире.

10 комментариев к записи

ошибка в таблице ! 0.044 не меньше чем 0.005 а больше почти в 9 раз!

Нет ошибки. Автор сравнивал скорости Python решений.

С++, который обгонит всё перечисленное:

Причем не особо кошерная реализация. Но соответствует предоставленному коду.
Кошерная реализация это:

Спасибо за приведенное полезное сравнение. Не хватает сравнения скорости записи (в рам для точности)

Необходимо установить соответствующую библиотеку numpy либо из репозиториев, либо посредством pip.

2 способ выдает:
[/, /, /]
при числах в файле:
1 2 3
4 5 6
7 8 9
Что не так?

Проверьте версию интерпретатора Python. В 3.7 работает нормально.

На С++ вы читали потоками, это медленно. Надо было попробовать функциями ввода вывода,fopen, fclose, fread должно быть быстрее. В С++ тоже несколько способов. Могло получиться сопоставимо с лучшим результатом.

На серьезных олимпиадах, а также во многих других ситуациях вам надо читать данные не с клавиатуры, а из файла, и выводить данные в файл, а не на "экран". В таком случае вы должны знать имена этих файлов; в задачах они, как правило, указаны, на этом сайте имена файлов почти всегда — input.txt для входных данных и output.txt для выходных.

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

Ввод данных

Самый простой способ ввести данные из файла в питоне — это сразу считать их в массив строк. Это делается так:

Здесь input.txt — файл, откуда надо считать данные, параметр "r" указывает, что вы собираетесь именно читать (read) данные, а не записывать (write, см. ниже). Команда open , как говорят, «открывает файл на чтение», а команда readlines считывает весь файл в массив строк.

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

то data будет содержать массив ["1 2 3\n", "4 5 6\n", "some text\n"] . (Здесь "\n" — это символ перевода строки, он будет на конце каждой строки массива data , кроме, возможно, последней. Если вы считываете числа, то можете о нем не беспокоиться, а если считываете строки и он вам мешает, то, как правило, от него можно избавиться командой a = a.rstrip("\n") , где a — строка, у которого вы хотите его убрать.)

Каждый элемент массива data — это как результат отдельной команды input() , которой вы пользовались для чтения с клавиатуры. Поэтому дальше вы пишете программу так же, как писали и раньше, но вместо каждого очередного обращения к input() вы обращаетесь к очередному элементу массива data . В простых случаях все просто, в более сложных вам надо аккуратно подсчитывать, к какому именно элементу массива вам надо обратиться.

Пример. Пусть во входном файле два числа по одному на строке. Их считываем так (здесь и далее слева — пример чтения с клавиатуры, справа — из файла):

Если же два числа в одной строке:

Более сложный пример: сначала число N , а потом N строк по одному числу в каждой:

Обратите внимание на то, что здесь написано i + 1 — потому что в первой (нулевой) строке было n .

Вывод

Проще всего выводить данные — записав их в одну большую строку и выведя эту строку. Вывод строки в файл делается так:

здесь s — строка, которую нужно вывести. Это должна быть именно строка, а не число и т.д. Используйте функцию str , чтобы превратить что угодно в строку, вручную добавляйте пробелы и переводы строк (перевод строки записывается так: "\n" ).

Пример: пусть надо вывести два числа в одну строку:

open("output.txt", "w").write(str(a) + " " + str(b))

Пусть надо вывести два числа на отдельных строках:

open("output.txt", "w").write(str(a) + "\n" + str(b))

Пусть надо вывести массив чисел по одному числу на строке:

или проще, используя строковую магию:

Имейте в виду, что такой вызов должен быть только один раз. Если вы хотите вызывать функцию write несколько раз, то надо суметь вызвать функцию open только один раз. Рекомендуемый вариант — такой:

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

Чтобы записать данные в файл и считать их из файла, язык программирования Python предлагает стандартные методы write() and read() для работы с одиночными строками, а также writelines() и readlines() для работы с множеством строк. Более того, модули pickle и json module предоставляют разумные способы работы с сериализованными наборами данных.

Использование методов read и write

Основные методы отлично работают с символами (строками). Построчное сохранение списка в файл listfile.txt работает следующим образом:

Использование методов writelines и readlines

Как упомянуто в начале этой статьи, Python также содержит два метода writelines() и readlines() , чтобы писать и читать множество строк за один шаг соответственно. Напечатать весь список в файл или на диск поможет следующий код на Python:

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

Открыв файл listfile.txt в строке 5, полностью переделываем список в строке 6. Сначала читаем содержимое файла через readlines() . Затем в цикле for удаляем окончание из каждой строки с помощью метода rstrip() . В конце добавляем строку к списку мест как новый элемент. По сравнению с прошлым листингом код получился более компактным, но его может быть сложнее прочесть начинающим программистам на Python.

Использование модуля pickle

Эти два примера показывают использование строк. Кстати, pickle работает со всеми видами объектов языка Python, такими как строки, числа, определённые в самом коде структуры, а также любые другие встроенные структуры данных Python.

Использование формата JSON

Используемый pickle формат двоичных данных специфичен для Python. Чтобы улучшить взаимодействие между различными программами, JavaScript Object Notation (JSON) предлагает лёгкую в использовании и читаемую для человека схему, и поэтому стал очень популярным.

Следующий пример показывает, как печатать список из элементов различных типов в выходной файл с помощью модуля json. В строке 4 определён основной список. Имея открытым файлом для записи в строке 7, метод dump() хранит основной список в файле, используя JSON.

Читать содержимое выходноо файла обратно в память так же просто, как записывать данные. Соответствующий dump() метод называется load() и работает следующим образом:

Вывод

Методы, показаные выше, разнятся от простой записи/чтенияя данных до сброса/загрузки через двоичные потоки с помощью pickle и JSON. Это значительно упрощает хранение списка и чтение его обратно в память.

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

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

Не используйте file.readlines() в for -loop, сам файл объекта достаточно: lines = [line.rstrip('\n') for line in file] В случае, если вы работаете с большими данными, использование readlines() не очень эффективно, так как это может привести к MemoryError . В этом случае лучше перебрать файл, используя for line in f: и работая с каждой line переменной. Я проверил профиль памяти различными способами, приведенными в ответах, используя процедуру, упомянутую здесь . Использование памяти намного лучше, когда каждая строка читается из файла и обрабатывается, как предлагает @DevShark здесь . Удерживать все строки в объекте коллекции не очень хорошая идея, если память ограничена или размер файла велик. Время выполнения одинаково в обоих подходах. Кроме того, .rstrip() будет работать немного быстрее, если вы удаляете пробелы с концов линий. Oneliner: with open(filename) as f: content = [i.strip() for i in f.readlines()]

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

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

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

Я предпочитаю этот ответ, поскольку он не требует загрузки всего файла в память (в этом случае он все еще добавляется, array хотя могут быть и другие обстоятельства). Конечно, для больших файлов этот подход может смягчить проблемы. Присоединение к массиву происходит медленно. Я не могу придумать случай использования, где это лучшее решение. @haccks это лучше, потому что он не загружает весь файл в память или там больше? Примечание: это решение не убирает новые строки. Это решение загружает весь файл в память. Я не знаю, почему люди так думают.

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

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

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

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

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

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

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

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

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

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

Обратите внимание, что у этого подхода есть 2 недостатка:

1) Вы храните все строки в памяти. В общем случае это очень плохая идея. Файл может быть очень большим, и вам может не хватить памяти. Даже если он не большой, это просто пустая трата памяти.

2) Это не позволяет обрабатывать каждую строку по мере их чтения. Поэтому, если вы обрабатываете ваши строки после этого, это неэффективно (требуется два прохода, а не один).

Лучший подход для общего случая был бы следующим:

Где вы определяете свою функцию процесса так, как хотите. Например:

(Реализация Superman класса оставлена ​​для вас как упражнение).

Это будет хорошо работать при любом размере файла, и вы пройдете его всего за 1 проход. Как правило, именно так будут работать универсальные парсеры.

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

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

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

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

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

Скрипт Python:

Используя append:

Или:

Или:

Или:

read().splitlines() предоставляется вам Python: это просто readlines() (что, вероятно, быстрее, так как это менее расточительно). @EricOLebigot из показанных примеров выглядит read().splitlines() и readlines() не выдает тот же результат. Вы уверены, что они эквивалентны? Если вы используете только readlines, вам нужно использовать метод strip, чтобы избавиться от \ n в тексте, поэтому я изменил последние примеры, используя понимание списка, чтобы иметь одинаковый вывод в обоих случаях. Итак, если вы используете read (). Readlines (), у вас будет «чистый» элемент со строкой и без символа перевода строки, в противном случае вы должны сделать то, что видите в приведенном выше коде. Верно. Обратите внимание, что в приведенном выше коде все символы strip() должны быть rstrip("\n") или пробелы вокруг строки удаляются. Кроме того, readlines() в понимании списка нет никакого смысла : лучше просто выполнять итерации по файлу, так как он не тратит время и память, создавая промежуточный список строк.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Чтение файла

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

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

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

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

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

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

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

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

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

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

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

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

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

Читайте также: