Python найти номер строки

Тренировка: как в Python найти номер строки с заданным вхождением

 Python найти номер строки

Как в 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 найти номер строки (или отыскать все строки) с заданным вхождением.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *