
Как в Python найти номер строки с заданным вхождением?
Как искать иголку в стоге сена мы выяснили, пришло время отыскать номер строки с заданным вхождением. А для того, чтобы поиски продвигались активнее, предлагаю поиграть в следователей – работа у них очень разноплановая: то преступника разыскивают, то код от сейфа.. Только представьте: следователи отыскали огромный текстовый файл, в котором тысячи строк. И лишь одна из них содержит фразу «я здесь ни при чем». А номер этой строки – недостающая часть кода от сейфа. Но мы же с вами — великие программисты! Мы сможем при помощи Python найти номер строки с заданными символами! Только составим предварительно ТЗ.
Кстати, а что, если в файле несколько строк с искомой фразой, и нам нужно вывести номера всех этих строк? Этот вариант мы не оставим без внимания и обязательно рассмотрим в этой статье в задаче №2. А сейчас приступим к решению первой задачи!
Задача №1: Поиск номера первой строки с заданным вхождением
Техническое задание:
Цель: вывести на экран номер строки, в которой содержится фраза: «я здесь ни при чем». Если таких строк несколько, выводим номер первой строки.
Порядок выполнения:
1. Инициализировать файл, в котором будем осуществлять поиск, а также определить искомую фразу.
2. Открыть заданный файл и произвести построчное считывание текста.
3. При считывании каждую строку файла проверять на вхождение фразы: «я здесь ни при чем». Если фраза в строке найдена, остановить построчное считывание и вывести номер строки на экран.
4. В заключение (исключительно в тренировочных целях!), оформим написанный код в функцию и осуществим ее вызов.
Для тренировки мы возьмем короткий файл — в нем легче протестировать работу нашего кода. Файл под названием «cats_fault.txt» следующего вида:
Если в домике бардак, Это котик виноват - Не помыл посуду кот, Думал, что и так сойдет Не заправил кот кровать, Начал с книжками играть.. И белье не постирал, и обед он наш украл.. В-общем, я здесь ни при чем, Это котик виноват :-)
Решение:
1. Инициализируем переменные:
Для начала укажем Питону, какой файл он проглотит на обед и где этот файл находится:
# Путь к текстовому файлу - замените на путь, по которому расположен файл на Вашем компьютере file_path = "path_to_file"
В приведенной выше строчке кода нужно поменять «path_to_file» на путь к вашему файлу. Если вы новичок и не знаете, как задать путь к файлу, прочитайте инструкцию по ссылке: «Как задать путь к файлу».
Затем определим искомую фразу:
# Путь к текстовому файлу - замените на путь, по которому расположен файл на Вашем компьютере file_path = "path_to_file" # Какую фразу будем искать: required = 'я здесь ни при чем'
2. Открываем файл и построчно считываем данные:
Откроем файл с помощью конструкции with open и оформим построчное считывание из файла с помощью функции enumerate() так, чтобы номер строки считывался в переменную num_line, а сама строка — в переменную line:
# Путь к текстовому файлу - замените на путь, по которому расположен файл на Вашем компьютере file_path = "path_to_file" # Какую фразу будем искать: required = 'я здесь ни при чем' # Считываем данные with open(file_path) as file: for num_line, line in enumerate(file):
Подробнее о построчном чтении файла можно прочитать по ссылке в статье “Построчное чтение файла в Python 3”.
3. Проверяем строки на вхождение искомой фразы
Добавим в цикл for проверку каждой считанной строки на вхождение фразы required. Как только такая строка будет найдена, выведем ее номер и выйдем из цикла с помощью break:
# Путь к текстовому файлу - замените на путь, по которому расположен файл на Вашем компьютере file_path = "path_to_file" # Какую фразу будем искать: required = 'я здесь ни при чем' # Считываем данные with open(file_path) as file: for num_line, line in enumerate(file): if required in line: print(num_line) break
Цель достигнута: номер строки найден!
Запускаем код и тестируем его работоспособность. Ура! Номер строки с фразой «я здесь ни при чем» выведен правильно! Обратите внимание, что по умолчанию, функция enumerate() производит нумерацию строк с нуля(не с единицы!), поэтому программа вывела на экран номер строки: 8.
Наведем красоту – поместим код в функцию!
Несмотря на то, что цель достигнута и программа успешно выводит номер строки с искомой фразой, предлагаю еще немного поработать. Давайте упакуем написанный код в функцию, а затем осуществим ее вызов с заданными параметрами: путем к файлу и искомой фразой. Выглядеть это будет так:
# Путь к текстовому файлу - замените на путь, по которому расположен файл на Вашем компьютере file_path = "path_to_file" # Затем определим искомую фразу: required = 'я здесь ни при чем' # Функция для поиска номера строки def find_string_number(path_to_file, required): with open(path_to_file) as file: for num_line, line in enumerate(file): if required in line: return(num_line) return('Ни одной строки с заданным содержанием не нашлось. Sorry. Это котик виноват') # Осуществим вызов функции string_number = find_string_number(file_path, required) print(string_number)
Результат работы скрипта: 8
Как работает скрипт?
Описанная выше функция find_string_number содержит два параметра: путь к файлу path_to_file и искомую фразу required. После открытия файла, производим построчное считывание с помощью функции enumerate(), в результате чего номер текущей строки считывается в переменную num_line, а текст строки в переменную line. В цикле if проверяем вхождение фразы required в строку line. Если вхождение найдено, то возвращаем номер строки и выходим из цикла for. Если после проверки всех строк, вхождение не было выявлено, возвращаем сообщение о провале операции: ‘Ни одной строки с заданным содержанием не нашлось. Sorry. Это котик виноват’.
Немного хвалебной речи и приглашение к участию в решении следующей задачи:
Отлично! Мы справились с заданием и научились находить первую строку в файле с искомой фразой! Теперь, опираясь на написанный выше код, мы легко сможем решить похожую задачу. На этот раз предлагаю не ограничиваться номером первой найденной строки, а вывести номера всех строк, содержащих искомую фразу! Да, и фразу поменяем: будем искать подстроку, порочащую честь ушастого: «Это котик виноват».
Задача №2: Выводим номера всех строк, содержащих искомое вхождение
Техническое задание:
Цель: вывести на экран номера всех строк, в которых содержится фраза: «Это котик виноват».
Порядок выполнения:
1. Инициализировать файл, в котором будем осуществлять поиск, а также определить искомую фразу.
2. Открыть заданный файл и произвести построчное считывание текста. При считывании каждую строку файла проверять на вхождение фразы: «это котик виноват». Если фраза в строке найдена, добавить номер строки в список string_numbers. Вывести все элементы списка string_numbers на экран.
Решение:
1. Инициализация переменных
Прежде всего предлагаю определиться, куда мы будем складывать найденные номера строк? На мой взгляд, массив — вполне пригодная тара для такого хранения. Поэтому помимо пути к файлу и переменной для хранения искомой фразы, инициализируем список: string_numbers:
# Путь к текстовому файлу - замените на путь, по которому расположен файл на Вашем компьютере file_path = "path_to_file" # Искомая фраза: required = 'Это котик виноват' # Пустой список для хранения найденных номеров строк string_numbers = []
2. Открываем файл, построчно считываем содержимое файла и проверяем каждую строку на вхождение подстроки required. Если вхождение найдено, добавляем номер строки в конец списка string_numbers. После проверки всех строк, выводим список на экран:
# Путь к текстовому файлу - замените на путь, по которому расположен файл на Вашем компьютере file_path = "path_to_file" # Искомая фраза: required = 'Это котик виноват' # Пустой список для хранения найденных номеров строк string_numbers = [] with open(file_path) as file: for num_line, line in enumerate(file): if required in line: string_numbers.append(num_line) print(string_numbers)
В результате работы скрипт отыскал 2 строки с вхождением required и вывел их в виде списка на экран:
[1, 9]
Финальное преображение кода: создаём функцию поиска номеров строк с заданным вхождением
А теперь, тренировки ради, предлагаю оформить написанный выше полезный код в красивую функцию под названием find_string_numbers() с двумя параметрами: file_path — содержит путь к файлу и required — содержит искомую фразу:
# Путь к текстовому файлу - замените на путь, по которому расположен файл на Вашем компьютере file_path = "path_to_file" # Искомая фраза: required = 'Это котик виноват' # Пустой список для хранения найденных номеров строк string_numbers = [] # Функция возвращает список номеров строк с заданным вхождением: def find_string_numbers(path_to_file, required_text): with open(path_to_file) as file: for num_line, line in enumerate(file): if required_text in line: string_numbers.append(num_line) if(len(string_numbers)>0): return(string_numbers) else: return("Ни одной строки с заданным содержанием не нашлось. Sorry. Это котик виноват") string_numbers = find_string_numbers(file_path, required) print(string_numbers)
В данном варианте, после прохождения цикла for и проверки всех считанных строк, добавлена проверка на длину списка. Если длина списка больше нуля, это значит, что, как минимум, одна строка содержит искомую фразу и функция find_string_numbers() возвращает список с номерами строк. В противном случае, функция вернет сообщение «Ни одной строки с заданным содержанием не нашлось. Sorry. Это котик виноват».
Подводим итог
Как показывает практика, в Python приятно иметь дело с файлами. Если открывать файл с помощью конструкции with, то можно не беспокоиться о его закрытии — python сделает эту работу за нас. А функция enumerate() самостоятельно пронумерует все строки файла. Так что нам останется проявить лишь немного навыков работы с циклами, чтобы с позволения Python найти номер строки (или отыскать все строки) с заданным вхождением.