Python: чтение текстовых файлов
Одна строка, последовательность чисел и записи с заголовком: чтение файла без потери значимых данных.
Файл может содержать одну длинную строку, числа по одному на строке или записи из нескольких полей. До вычислений нужно превратить этот текст в данные программы. Способ чтения определяется устройством файла: заголовок не становится первым объектом, а перевод строки не должен попасть в исследуемый фрагмент.
Открытие и расположение файла
open() открывает файл, а переменная f позволяет читать его содержимое. Конструкция with закрывает файл при выходе из своего блока. Отступ показывает, какие команды выполняются внутри этого блока. Полученные строка или список остаются доступны после его окончания.
with open("data.txt") as f:
text = f.read()
print(text)
Имя data.txt ищется в рабочей папке. Поэтому наличие файла рядом с программой не всегда означает, что он будет найден. При ошибке FileNotFoundError проверяются фактическое имя, распаковка архива и рабочая папка. Имя архива с расширением .zip нельзя подставлять вместо имени текстового вложения.
Одна значимая строка
readline() читает следующую строку вместе с завершающим переводом строки, если он есть. В задании №24 строка из букв обычно читается так:
name = "88B226.txt"
with open(name) as f:
s = f.readline().strip()
print(len(s))
strip() удаляет пробельные символы с обоих краёв. Для строки только из букв это убирает служебный конец строки. Если пробелы являются частью условия, такая обработка изменит данные. Тогда удаляется только окончание строки, например line.rstrip("\n") при обычном текстовом чтении. Внутренние пробелы этот вызов сохраняет.
read() получает весь оставшийся текст, а не только одну строку. Для нескольких значимых строк замена readline() на read() не безразлична: между ними останутся переводы строк. Удалять их автоматически нельзя, поскольку склейка может создать новое соседство символов.
Числа по одному на строке
Текст "12" ещё не число. Функция int() превращает целочисленную запись в число. Цикл по f последовательно получает строки до конца файла; отдельная команда чтения внутри такого цикла не нужна.
with open("17.txt") as f:
a = []
for line in f:
a.append(int(line))
Если учебный файл содержит строки 12, -5, 8, получится список [12, -5, 8]. Завершающий перевод строки не мешает int(). Пустая строка, напротив, не является целым числом: её появление требует сверки формата, а не безусловного пропуска всех неудобных строк.
Заголовок и поля записи
Пусть первая строка учебного файла содержит количество объектов, а каждая следующая — два числа. Заголовок читается отдельно. Метод split() без аргументов делит строку по пробельным промежуткам; map(int, ...) применяет преобразование к каждому полю.
with open("26.txt") as f:
n = int(f.readline())
rows = []
for line in f:
x, y = map(
int,
line.split()
)
rows.append((x, y))
print(n, len(rows))
Для заголовка 2 и записей 3 8, 5 9 печатается 2 2. Смысл полей сохраняется: если первое число означает начало мероприятия, его нельзя переставить с концом ради удобства сортировки. При нескольких числах в заголовке он тоже разбивается на поля по описанию задания.
Возможные ловушки
Повторное чтение продолжает работу с текущего места: после readline() цикл получает оставшиеся строки. После полного чтения второй read() вернёт пустую строку. Если сведения нужны повторно, используются уже сохранённые данные либо файл открывается заново.
Какая часть файла описывает объекты, а какая задаёт параметры? Нужно ли хранить все строки или достаточно текущей? Ответ определяет способ чтения до начала основного алгоритма.