Построчное чтение файла на Python

* Введение * Базовый файловый ввод-вывод в Python * Построчное чтение * Пример приложения * Заключение Введение В течение моей работы у меня была возможность использовать множество концепций программирования и технологий для бесчисленных вещей. Некоторые из этих вещей связаны с относительно низкими результатами моего труда, такими как автоматизация подверженных ошибкам или рутинных задач, таких как создание отчетов, автоматизация задач и общее переформатирование данных. Другие были гораздо более ценными, например, разработка

Вступление

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

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

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

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

Базовый файловый ввод-вывод в Python

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

 fp = open('path/to/file.txt', 'r') 

Функция open() принимает несколько аргументов. Мы сосредоточимся на первых двух, причем первый - это позиционный строковый параметр, представляющий путь к файлу, который должен быть открыт. Второй необязательный параметр также является строкой, которая определяет режим взаимодействия, который вы предполагаете для файлового объекта, возвращаемого вызовом функции. Наиболее распространенные режимы перечислены в таблице ниже, по умолчанию для чтения установлено значение «r».

Режим Описание


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

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

 fp.close() 

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

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

 with open('path/to/file.txt') as fp: 
 # do stuff with fp 

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

 try: 
 fp = open('path/to/file.txt') 
 
 # do stuff with fp 
 finally: 
 fp.close() 

Подходит любой из этих двух методов, причем первый пример более "питонический".

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

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

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

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

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

Примечание . В оставшейся части этой статьи я буду демонстрировать, как читать в тексте книги «Илиада Гомера», которую можно найти на сайте gutenberg.org , а также в репозитории GitHub, где есть код для этого. статья.

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

 filepath = 'Iliad.txt' 
 with open(filepath) as fp: 
 line = fp.readline() 
 cnt = 1 
 while line: 
 print("Line {}: {}".format(cnt, line.strip())) 
 line = fp.readline() 
 cnt += 1 

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

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

 $ python forlinein.py 
 Line 0: BOOK I 
 Line 1: 
 Line 2: The quarrel between Agamemnon and Achilles--Achilles withdraws 
 Line 3: from the war, and sends his mother Thetis to ask Jove to help 
 Line 4: the Trojans--Scene between Jove and Juno on Olympus. 
 Line 5: 
 Line 6: Sing, O goddess, the anger of Achilles son of Peleus, that brought 
 Line 7: countless ills upon the Achaeans. Many a brave soul did it send 
 Line 8: hurrying down to Hades, and many a hero did it yield a prey to dogs and 
 Line 9: vultures, for so were the counsels of Jove fulfilled from the day on 
 ... 

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

 filepath = 'Iliad.txt' 
 with open(filepath) as fp: 
 for cnt, line in enumerate(fp): 
 print("Line {}: {}".format(cnt, line)) 

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

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

Было бы упущением написать приложение о том, как использовать информацию в текстовом файле, не продемонстрировав хотя бы тривиального использования того, как использовать такой достойный навык. При этом я продемонстрирую небольшое приложение, которое можно найти в wordcount.py, которое вычисляет частоту каждого слова, присутствующего в «Илиаде Гомера», использованного в предыдущих примерах. Это создает простой набор слов , который обычно используется в приложениях НЛП.

 import sys 
 import os 
 
 def main(): 
 filepath = sys.argv[1] 
 
 if not os.path.isfile(filepath): 
 print("File path {} does not exist. Exiting...".format(filepath)) 
 sys.exit() 
 
 bag_of_words = {} 
 with open(filepath) as fp: 
 cnt = 0 
 for line in fp: 
 print("line {} contents {}".format(cnt, line)) 
 record_word_cnt(line.strip().split(' '), bag_of_words) 
 cnt += 1 
 sorted_words = order_bag_of_words(bag_of_words, desc=True) 
 print("Most frequent 10 words {}".format(sorted_words[:10])) 
 
 def order_bag_of_words(bag_of_words, desc=False): 
 words = [(word, cnt) for word, cnt in bag_of_words.items()] 
 return sorted(words, key=lambda x: x[1], reverse=desc) 
 
 def record_word_cnt(words, bag_of_words): 
 for word in words: 
 if word != '': 
 if word.lower() in bag_of_words: 
 bag_of_words[word.lower()] += 1 
 else: 
 bag_of_words[word.lower()] = 1 
 
 if __name__ == '__main__': 
 main() 

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

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

Заключение

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

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

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus