Сравнение строк в Python: «is» против «==»
Часто при работе с Python возникает необходимость сравнивать строки. На первый взгляд, кажется, что операторы «is» и «==» выполняют одну и ту же функцию. Однако на практике они работают по-разному.
Возьмем вот такой пример:
a = 'Hello, world!' b = ''.join(['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']) print(a == b) # True print(a is b) # False
Оба оператора «==» и «is» сравнивают две строки, но делают это по-разному.
Оператор «==» проверяет равенство значений. В случае со строками он проверяет, состоят ли они из одинаковых символов в одинаковом порядке. В примере выше a == b возвращает True , потому что строки a и b состоят из одинаковых символов в одинаковом порядке.
Оператор «is», напротив, проверяет идентичность объектов. Он возвращает True , только если оба операнда являются одним и тем же объектом, то есть занимают одно и то же место в памяти. В примере выше a is b возвращает False , потому что, несмотря на то что a и b представляют один и тот же текст, они хранятся в разных местах памяти.
В большинстве случаев при сравнении строк следует использовать оператор «==», так как он корректно проверяет равенство значений.
Что же касается сравнения чисел и булевых значений, то здесь также в большинстве случаев следует использовать «==». Оператор «is» может вести себя неочевидно, особенно при работе с числами. В общем случае, «is» следует использовать только тогда, когда нужно проверить, являются ли две переменные одним и тем же объектом, то есть указывают ли они на одно и то же место в памяти.
Сравнение строк Python 3
В 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-тренды, делятся полезными инструкциями и даже приглашают к себе работать.
Как сравнить строки Python
Строки в Python – это последовательности символов, заключенные в кавычки. Они используются в основном для записи текстовой информации. Иногда программисты сталкиваются с необходимостью сравнить их, чтобы получить некоторый результат. Как и с обычными числами, последовательности символов можно сравнивать. Однако у этого процесса есть свои особенности, о которых мы поговорим немного позже.
В настоящей инструкции будут разобраны возможные способы сравнения строк в Python и приведены наглядные примеры для каждого из них.
Операторы сравнения
Чтобы сравнить 2 строки в Python , необходимо изучить работу соответствующих операторов.
Ниже в таблице мы разберем существующие операторы сравнения, а также приведем примеры для наглядного понимания принципа их работы. В примерах мы будем использовать неравные между собой последовательности символов «dog» и «cat».
Оператор больше или равно.
Оператор меньше или равно.
Все рассмотренные в таблице операторы возвращают true, если условие сравнения выполняется. В противоположном случае они возвращают false.
В случае с последними четырьмя операторами из таблицы, происходит посимвольное сравнение. Сначала берутся первые символы каждой последовательности, затем вторые символы и т.д. Также стоит учитывать, что одинаковые символы не будут равными, если они имеют разный регистр. Так, например, символ «X» будет иметь меньшее значение, чем «x». Чтобы узнать порядковое значение символа, используется следующая команда:
ord(символ)
Например, найдем порядковое значение буквы «X» с верхним регистром и буквы «x» с нижним:
print('Порядковое значение Х = ', ord('X'), '; а x = ', ord('x'))
Результат продемонстрирован на картинке ниже.
Также стоит упомянуть, что при сравнении двух последовательностей символов, имеющих одинаковые подстроки в начале (например, «Orange» и «Orange Juice»), большей будет та, у которой количество символов больше.
Сравнение строк, введенных с клавиатуры
В данной главе мы рассмотрим сравнение последовательностей символов, ввод которых был осуществлен с клавиатуры. Для этого мы будем использовать операторы сравнения ( == , != , < , >, = ), которые были подробно разобраны в прошлой главе.
Итак, для того, чтобы сравнить две строки в Python , введенные с клавиатуры, напишем следующий код:
first_string = input('Введите первую строку:\n')
second_string = input('Введите вторую строку:\n')
if first_string > second_string:
print(f"В словаре последовательность расположена после последовательности ")
elif first_string < second_string:
print(f"В словаре последовательность расположена перед последовательностью ")
else:
print(f"Строки и - одинаковы!")
В данном коде мы считываем две последовательности символов с помощью функции input() , а затем отрабатываем все возможные случаи, используя конструкцию if-elif-else . Попробуем ввести разные последовательности символов и посмотрим на результат.
Вводим слова «озеро» и «река»:
Теперь введем те же слова, но наоборот. Сначала «река», а потом «озеро»:
И, наконец, введем две одинаковые последовательности:
Сравнение строк без учета регистра
В предыдущих разделах мы несколько раз обращали ваше внимание на важность регистров при сравнении последовательности символов. Однако это можно обойти, используя встроенные методы языка.
Чтобы сравнить строку со строкой в Python без учета регистра, необходимо использовать методы строки upper() и противоположный ему lower() . Первый приводит последовательность символов полностью к верхнему регистру, а второй соответственно к нижнему. Их синтаксис выглядит следующим образом:
строка.upper()
строка.lower()
Давайте рассмотрим работу методов более детально на примере:
example_string1 = 'orange'
example_string2 = 'ORANGE'
print(example_string1 == example_string2)
print(example_string1.upper() == example_string2)
print(example_string1 == example_string2.lower())
В примере выше мы создаем 2 строковые переменные типа string и передаем им одинаковые значения, но в разном регистре. Далее мы выводим на экран три результата сравнения. В первом случае мы сравниваем исходные последовательности. Во втором используем метод upper() , чтобы привести первую строку к верхнему регистру, после чего выполняем сравнение. И, наконец, в третьем приводим вторую последовательность к нижнему регистру.
Как видно по картинке выше, в первом случае последовательности символов не равны друг другу, так как они переданы с разным регистром, а во втором и третьем – равны, так как над ними были выполнены преобразования.
Использование методов языка
В данном разделе инструкции мы разберем существующие методы строк, которые также помогут пользователю выполнить сравнение.
Метод __eq__
Первый рассматриваемый метод – __eq__() . Он равнозначен оператору == , который мы рассматривали в самой первой главе инструкции. Его синтаксис, в отличие от других языков программирования, выглядит следующим образом:
первая_строка.__eq__(вторая_строка)
Теперь приведем пример, в котором воспользуемся этим методом:
first_string = input('Введите первую строку:\n')
second_string = input('Введите вторую строку:\n')
if first_string.__eq__(second_string):
print("Последовательности <> и <> - одинаковы!".format(first_string,second_string))
else:
print("Последовательности <> и <> - разные!".format(first_string,second_string))
В результате выполнения кода мы получим следующее:
Методы startswith() и endswith()
Следующие два метода, которые мы рассмотрим, – startswith() и endswith() . Первый из двух методов используется в тех случаях, когда необходимо выполнить сравнение элементов строки в Python , расположенных в ее начале, с заданным шаблоном символов. Второй работает точно так же, но сравнивает не с началом последовательности, а с ее концом.
Синтаксис startswith() и endswith() выглядит следующим образом:
исходная_строка.startswith(шаблон)
исходная_строка.endswith(шаблон)
Рассмотрим их применение на примере ниже:
example_string = "Строка написана для проверки работы метода"
print(example_string.startswith("Строка"))
print(example_string.endswith("метода"))
Результат работы кода представлен на картинке ниже.
Использование регулярных выражений
Кроме рассмотренных методов и операторов в Python возможно использовать регулярные выражения для сравнения строк.
Регулярные выражения – это определенный шаблон символов, по которому происходит отбор строк. Пользователь может создать уникальный шаблон и сравнить с ним необходимые строки или целый текст.
В качестве примера создадим список, содержащий название ягод на английском языке, и регулярное выражение, которое будет сравниваться с ними и возвращать только те последовательности, что содержат в своем название подстроку «berry».
Ниже напишем код для реализации поставленной задачи. Чтобы использовать регулярные выражения в своем коде, необходимо в первую очередь импортировать модуль re .
import re
example_list = ['cowberry', 'watermelon', 'cherry', 'blackberry']
expression = re.compile('berry')
for berry in example_list:
if expression.search(berry):
print(f" - эта ягода содержит подстроку berry в своем название")
В результате, после сравнения регулярного выражения со списком названий ягод, мы получаем следующее:
Как видно по картинке выше, всего две ягоды подошли под созда нный нами фильтр.
Заключение
В данной инструкции были продемонстрированы основные способы сравнения строк в Python. Все они уникальны по-своему, поэтому выбор того или иного способа зависит от конкретной ситуации. Надеемся, что после прочтения статьи, данный процесс не будет вызывать у вас затруднений.
Как сравнить элементы в списке?
Потому что у типа list не существует метода set() . Вместо этого предлагаю просто обернуть set(a) в list() — программа самостоятельно превратит множество (без повторяющихся элементов) в список:
a = [('германия', ), ('германия', ), ('япония', )] print(list(set(a))) ----- [('япония',), ('германия',)]
Отслеживать
ответ дан 16 янв 2022 в 11:48
3,908 4 4 золотых знака 9 9 серебряных знаков 22 22 бронзовых знака
отлично, действительно помогло! спасибо!! осталось узнать как убрать лишние символы
16 янв 2022 в 11:53
@uw935 о каких лишних символах идёт речь? Можете конкретизировать?
16 янв 2022 в 11:54
лишние символы типа: скобки, кавычки, запятые: (),»
16 янв 2022 в 11:55
@uw935 Это не «лишние» символы. Кавычки показывают, что это строка. Запятая в скобках — что там кортеж. Чтобы превратить этот список в планарный, можно сделать a = [x[0] for x in a] или a = list(list(zip(*a))[0]) или a = list(sum(a, ())) .
