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

Сравнение строк Python 3

Команда Timeweb Cloud
Команда Timeweb Cloud
Наши инженеры, технические писатели, редакторы и маркетологи
23 августа 2022 г.
8662
6 минут чтения
Средний рейтинг статьи: 3

New Documentation

В Python сравнение строкэто сравнение их символов по отдельности, которое происходит последовательно. Сначала сравниваются первые символы, затем — вторые, дальше — третьи и так далее, пока не закончатся обе строки. При этом учитываются не сами символы, а их значения Unicode.

Простое сравнение

Чтобы выполнить в Python сравнение строк на похожесть, используют операторы == (равно) и != (не равно).

Оператор == вернёт True в том случае, если строки совпадают, и False — если они не совпадают. Оператор != работает наоборот: он возвращает True, если значения отличаются.

В качестве примера сравните название хостера. Выполните следующий код:

hoster = 'cloud'
print(hoster == 'cloud')
print(hoster != 'cloud')

В первом случае вы получите ответ True, во втором — False.

Теперь попробуйте изменить значение переменной. Напишите название с большой буквы, а при сравнении используйте название с маленькой буквы:

hoster = 'Cloud'
print(hoster == 'cloud')
print(hoster != 'cloud')

Результат будет противоположный. Первый print() вернёт False, а второй – True. Всё потому, что  'Cloud' != 'cloud'. 

Чтобы понять, как здесь сработало сравнение символов в строке Python, используйте функцию ord(). Она показывает значение Unicode, переданное в качестве аргумента символа.

Выполните:

print(ord('C'))

В ответ вы получите число 67. Это значение Unicode большой буквы 'C'.

Затем проделайте то же самое с маленькой буквой:

print(ord('c'))

В ответ вы получите число 99.

Важность регистра

Разница в значениях Unicode в посимвольном сравнении строк на Python очень важна. Например, вы хотите создать квиз. Пользователь должен вводить ответы на вопросы в поля формы. Задача программы — обработать полученные ответы и сравнить их с данными, которые хранятся в базе. Если ответ совпадает, пользователь получает 1 балл.

В нашем примере сравнение останавливается после проверки первых символов. Интерпретатор Python видит, что в последовательности Unicode буква ‘С’ встречается раньше, чем буква ‘с’. Значит, строка, которая начинается с неё, будет меньше.

Пользователи могут вводить одни и те же слова по-разному — писать с маленькой буквы, с большой, через Caps Lock. Хранить подходящие значения нереально. И не нужно. Гораздо проще приводить всё к единому виду. Например, с помощью метода lower().

Проверьте, как выполнится в Python сравнение строк без учёта регистра:

hoster1 = 'Cloud'
hoster2 = 'cloud'
print(hoster1 == hoster2)

Вернётся False, потому что значения разные.

С методом lower():

hoster1 = 'Cloud'
hoster2 = 'cloud'
print(hoster1.lower() == hoster2.lower())

Вернётся True. Метод lower() приводит все символы к нижнему регистру. Теперь не имеет значения, в каком виде передана строка. Программа приведет ее к заданному вами стандарту и сравнит с тем ответом, который хранится в базе данных.

Сравнение двух строк Python можно выполнить не только на равенство, но и на больше или меньше. Возьмём тот же пример, но используем другие операторы.

Код:

hoster1 = 'Cloud'
hoster2 = 'cloud'
print(hoster1 > hoster2)

вернёт False, потому что значение Unicode у буквы ‘С’ меньше, чем у ‘с’ — 67 против 99. Если же поменять оператор:

hoster1 = 'Cloud'
hoster2 = 'cloud'
print(hoster1 < hoster2)

то вернётся True. Так работает лексикографическое сравнение строк на Python каждый символ в одной строке по очереди сравнивается с символом в другой строке.

Сравнение с помощью is

В Python всё — это объект. Строки не исключение. Поэтому их можно сравнивать не только по фактическому значению, но и по идентификатору экземпляра объекта. 

Проще разобраться на примере. Задайте две переменные с одинаковым значением. Пусть это тоже будет название хостера.

hoster1 = cloud’
hoster2 = ‘cloud’

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

if hoster1 == hoster2:
print(‘Это один и тот же хостер’)
else: 
print(‘Это разные хостеры’)

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

Теперь проверьте, одинаковые ли идентификаторы у обоих экземпляров объекта. Используйте для этого оператор ‘is’. Если обе переменные указывают на один объект, он возвращает True. В противном случае — False.

Проблема в том, что даже если строки имеют одинаковое значение, в ответ вы можете получить False, потому что переменные указывают на разные экземпляры объекта.

Чтобы оптимизировать работу со строками, Python выполняет интернирование. Суть метода проста. Для некоторых неизменяемых объектов в памяти хранится только один экземпляр. Когда вы пишете в двух или более переменных одинаковые значения, они обычно ссылаются на одну ячейку памяти. Поэтому в некоторых случаях оператор is возвращает True.

Но важно помнить об одной особенности. Интернирование происходит до выполнения кода. Поэтому, например, такая программа вернёт False:

hoster1 = 'cloud'
hoster2 = 'cl'
print(hoster1, 'и', hoster2 + 'oud', 'это один и тот же хостер:', hoster1 is hoster2)
#Output:
cloud и cloud это один и тот же хостер: False

Здесь вы изначально задали переменным разные значения. Поэтому они стали ссылаться на разные экземпляры объекта.

Чтобы избежать проблем в больших программах, при сравнении по идентификаторам необходимо явно интернировать строки. Для этого в Python используется метод intern.

import sys
a = sys.intern(‘string’)
b = sys.intern(‘string’)
a is b
True

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

Нечёткое сравнение

Допустим, вы хотите сделать программу с парсером и RSS, которая будет собирать новости из разных источников. Чтобы новости не дублировались, нужно сравнивать заголовки. Делать это посимвольно бессмысленно — каждое новостное агентство придумывает свой заголовок. Здесь на помощь приходит нечёткое сравнение.

Нечёткое сравнение строк на Python реализовано в библиотеке thefuzz. Алгоритм сравнения основан на расстоянии Левенштейна, которое показывает разность между двумя последовательностями символов.

Установите библиотеки thefuzz и python-Levenshtein:

pip install thefuzz
pip install python-Levenshtein

Импортируйте библиотеку в файл:

from thefuzz import fuzz as f 

Выполните простое сравнение:

f.ratio(‘Хостер Cloud’, ‘Cloud хостер’)

Максимально возможный результат— 100. Вы увидите его, если передадите идентичные значения.

Библиотеку thefuzz также можно использовать для поиска подстрок без регулярных выражений. Например:

from thefuzz import fuzz as f 
f.partial_ratio(‘Здесь будем искать упоминание Cloud’, ‘Cloud’)

В ответ вы получите 100 — подстрока встречается точно в таком виде.

Ещё один мощный метод  — WRatio. Он обрабатывает разные регистры, а также знаки препинания и некоторые другие параметры. Например, такое сравнение:

f.WRatio(‘Хостер Компания CLOUD!!!’, ‘КоМпАнИя,,, ClouD Хостер’)

вернёт совпадение 95 из 100. 

Мы рассмотрели основные методы библиотеки thefuzz, которые помогают выполнить сравнение строк в Python 3. Посмотреть другие примеры вы можете в репозитории библиотеки на GitHub.

Кстати, в официальном канале Timeweb Cloud мы собрали комьюнити из специалистов, которые говорят про IT-тренды, делятся полезными инструкциями и даже приглашают к себе работать.

Зарегистрируйтесь и начните пользоваться
сервисами Timeweb Cloud прямо сейчас

15 лет опыта
Сосредоточьтесь на своей работе: об остальном позаботимся мы
165 000 клиентов
Нам доверяют частные лица и компании, от небольших фирм до корпораций
Поддержка 24/7
100+ специалистов поддержки, готовых помочь в чате, тикете и по телефону