Сравнение строк в Python
Сравнение строк в Python можно выполнить с помощью операторов равенства (==) и сравнения (,! =, =). Специальных методов для сравнения двух строк не существует.
Сравнение строк выполняется с использованием символов в обеих строках. Символы в обеих строках сравниваются один за другим. Когда обнаруживаются разные символы, сравнивается их значение Unicode. Символ с меньшим значением Unicode считается меньшим.
Давайте рассмотрим несколько примеров для сравнения строк.
fruit1 = 'Apple' print(fruit1 == 'Apple') print(fruit1 != 'Apple') print(fruit1 < 'Apple') print(fruit1 >'Apple') print(fruit1 = 'Apple')
True False False False True True
Обе строки абсолютно одинаковы, следовательно, они равны. Таким образом, в этом случае оператор равенства возвращает True.
Давайте посмотрим на другой пример, в котором мы будем получать данные от пользователя, а затем сравнивать их.
fruit1 = input('Please enter the name of first fruit:\n') fruit2 = input('Please enter the name of second fruit:\n') if fruit1 < fruit2: print(fruit1 + " comes before " + fruit2 + " in the dictionary.") elif fruit1 >fruit2: print(fruit1 + " comes after " + fruit2 + " in the dictionary.") else: print(fruit1 + " and " + fruit2 + " are same.")
Please enter the name of first fruit: Apple Please enter the name of second fruit: Banana Apple comes before Banana in the dictionary. Please enter the name of first fruit: Orange Please enter the name of second fruit: Orange Orange and Orange are same.
Посмотрим, учитывается ли при сравнении регистр или нет? Также, если «а» идет «а»?
print('apple' == 'Apple') print('apple' > 'Apple') print('A unicode is', ord('A'), ',a unicode is', ord('a'))
False True A unicode is 65 ,a unicode is 97
Таким образом, «Apple» меньше, чем «apple», из-за их значений Unicode. Мы используем функцию ord() для печати значения кодовой точки Unicode символов.
Что, если одна из строк состоит из второй строки и некоторых дополнительных символов?
print('Apple' < 'ApplePie')
Если последовательность символов одинакова в обеих строках, но одна из них имеет некоторые дополнительные символы, то строка большей длины считается больше, чем другая.
Что, если мы используем операторы для сравнения двух равных строк?
print('apple' < 'apple') print('apple' >'apple')
False False
Очевидно, обе строки ни меньше, ни больше, чем другая. Следовательно, в обоих случаях результат неверен.
Строки
Строки предоставляют возможность хранить и оперировать с данными, представленными в виде последовательности символов. Язык Python из "коробки" имеет широкую поддержку строк и позволяет обращаться с символами из самых разных алфавитов.
Тип str
Для взаимодействия со строками в языке есть встроенный тип str . Его литералом являются одиночные ' или двойные кавычки " . Символы (код), заключенный между кавычками будет восприниматься Python, как строка:
>>> s1 = 'Привет! Я строка!' >>> s2 = "Привет! Я тоже строка!" >>> type(s1) >>> type(s2)
Строка может быть пустой: '' или "" .
Чтобы воспользоваться кавычками внутри строки, есть два пути:
- Воспользоваться в качестве литерала одним видом кавычек, а внутри строки пользоваться вторым видом кавычек;
- Экранировать кавычки внутри строки с помощью символа экранирования (escape character) \, он же называется обратной косой чертой.
>>> s4 = '\'Я внутри одинарных кавычек\', а "я внутри двойных"' >>> s4 '\'Я внутри одинарных кавычек\', а "я внутри двойных"' >>> print(s4) 'Я внутри одинарных кавычек', а "я внутри двойных"
Здесь в качестве литерала взяты одинарные кавычки, для первой части фразы используется экранирование, а для второй двойные.
Более того, для удобного написания многострочной строки (простите), можно воспользоваться тройными одинарными или тройными двойными кавычками, причём внутри такой строки экранирование не понадобится:
>>> multiline_str = '''Я первая строка . I'm the second line . А я третья!''' >>> multiline_str "Я первая строка\nI'm the second line\nА я третья!" >>> print(multiline_str) Я первая строка I'm the second line А я третья!
Заметьте, что во второй строке экранирование кавычки не понадобилось ( I'm ).
Также, вы могли заметить, что при вызове в интерактивном режиме строка отображается в виде, в котором представлена в программе, и только при печати print() отображается ожидаемо. В случае печати чисел это было не заметно.
Напоследок, небольшой список часто используемых экранированных последовательностей (escape sequence):
- символ новой строки \n
- табуляция \t , с помощью табуляции можно получать удобные для чтения таблицы
- кавычки \' , \"
- обратная косая \\
Доступ к символам и срезы строк
Так же, как и список, строка это упорядоченная последовательность. Если список это последовательность объектов произвольного типа, то строка это последовательность символов.
Можно узнать длину строки, получить символ на определённой позиции и даже получить срез строки:
>>> s = "Hello, World!" >>> len(s) 13 >>> s[0] 'H' >>> s[7:] 'World!' >>> s[::2] 'Hlo ol!'
Конкатенация и неизменяемость строк
Простейшая операция над двумя строками это конкатенация - приписывание второй строки в конец первой:
>>> str_1 = "ABC" >>> str_2 = "def" >>> str_1 + str_2 'ABCdef' >>> str_2 + str_1 'defABC'
Более того, с помощью символа умножения * можно конкатенировать строку с самой собой несколько раз:
>>> str_1 'ABC' >>> str_1 * 10 'ABCABCABCABCABCABCABCABCABCABC' >>> 5 * str_1 'ABCABCABCABCABC' >>> str_1 'ABC' >>> str_2 'def' >>> (str_1 + str_2) * 5 'ABCdefABCdefABCdefABCdefABCdef'
Строки являются неизменяемым типом в Python. При попытке изменения символа на какой-то позиции произойдёт ошибка:
>>> s = 'ваза' >>> s[0] = 'б' Traceback (most recent call last): File "", line 1, in TypeError: 'str' object does not support item assignment
На самом деле, в примерах по конкатенации Python создавал новые объекты строк. Даже операция инкрементирования создаёт новую строку, в чём можно убедиться, узнав их идентификатор (в данном случае это равносильно адресу в памяти):
>>> s = 'a' >>> id(s) 4465232176 >>> s += 'b' >>> s 'ab' >>> id(s) 4466564720
Сравнение строк
Строки в Python можно сравнивать между собой.
Сначала посмотрим на сравнение символов.
>>> '0' '1' True >>> 'a' 'b' True >>> '.' ',' False
И если с символами 0, 1 , a, b результат интуитивен, то последнее сравнение (знаков препинания) неочевидно.
Не будем гадать. Существует кодовая таблица символов, которая приписывает каждому символу порядковый номер. При сравнении символов сравниваются их порядковые номера.
В языке Python, чтобы узнать порядковый номер символа, воспользуйтесь функцией ord(s)
>>> '.' ',' False >>> ord('.') 46 >>> ord(',') 44 >>> 46 44 False
Сразу приведём функцию, обратную функции ord , это функция chr(i)
>>> ord('a') 97 >>> chr(97) 'a'
Историческим стандартом кодовых таблиц символов является таблица ASCII (American standard code for information interchange). Изначально таблица содержала 128 символов (по 7 бит на символ), затем она была расширена до 256 символов, где первые 128 символов остались без изменений, а вторая половина отводилась под национальные алфавиты, что породило множество национально-специфичных кодировок.
Современный стандарт - кодировка Unicode. Python работает с ней. Целью данной кодировки является создать "алфавит" для любых естественных и выдуманных языков и символов вообще. В Unicode первые 128 символов - символы ASCII.
Рекомендуется ознакомиться с таблицей ASCII. Например, здесь. Вы заметите, что символы алфавитов расположены в алфавитном порядке. Как раз за этим и кроется "интуитивность" сравнения 'a' < 'b' .
В Unicode также сохраняется этот удобный паттерн и для других языков, но стоит быть осторожным
>>> 'б' 'ё' True >>> 'Б' 'Ё' False
Поскольку, скажем, буквы расположены непрерывно в ASCII, то вы можете проверять, является ли символ буквой (строчные и заглавные случаи нужно рассматривать отдельно).
>>> 'a' '0' 'z' False >>> 'a' 'y' 'z' True
Аналогично этому примеру попробуйте написать условие проверки символа на десятичную цифру.
Итак, отдельные символы сравниваются по их порядковым номерам. Как же сравниваются строки? Всё просто. Так же, как слова отсортированы в словаре в алфавитном порядке, так же и в машинном представлении, только алфавитом является кодовая таблица (в случае Python это Unicode).
То есть, сравниваем строки посимвольно слева направо. Если символы разные, то меньшей строкой является та, у которой порядковой номер символа меньше. Если же символы одинаковые, то сравниваем следующие два символа. Если мы достигли конца одной строк в таком сравнении, до сих пор не выявив, кто меньше, то меньшей считается более короткая строка.
>>> 'aa' 'aaa' True >>> 'ab' 'aaa' False
В первом примере первые два символа строк совпадают, однако в строке aa два символа, а в строке aaa — три. В этом случае меньшей строкой является та, что короче.
Во втором примере первые два символа совпадают, вторые же нет. Поскольку порядок ord('b') > ord('a') , то получаем False .
Некоторые методы строк
У строк в Python огромное количество методов. Не верите? Вот они:
str.capitalize() str.casefold() str.center(width[, fillchar]) str.count(sub[, start[, end]]) str.encode(encoding="utf-8", errors="strict") str.endswith(suffix[, start[, end]]) str.expandtabs(tabsize=8) str.find(sub[, start[, end]]) str.format(*args, **kwargs) str.format_map(mapping) str.index(sub[, start[, end]]) str.isalnum() str.isalpha() str.isascii() str.isdecimal() str.isdigit() str.isidentifier() str.islower() str.isnumeric() str.isprintable() str.isspace() str.istitle() str.isupper() str.join(iterable) str.ljust(width[, fillchar]) str.lower() str.lstrip([chars]) static str.maketrans(x[, y[, z]]) str.partition(sep) str.replace(old, new[, count]) str.rfind(sub[, start[, end]]) str.rindex(sub[, start[, end]]) str.rjust(width[, fillchar]) str.rpartition(sep) str.rsplit(sep=None, maxsplit=-1) str.rstrip([chars]) str.split(sep=None, maxsplit=-1) str.splitlines([keepends]) str.startswith(prefix[, start[, end]]) str.strip([chars]) str.swapcase() str.title() str.translate(table) str.upper() str.zfill(width)
Мы разберём только некоторые из них (для остальных есть help(str.method_name) 🙂
Поиск
Метод str.find ищет подстроку в строке и возвращает индекс начала найденной подстроки. Если вхождение не найдено, вернётся -1:
>>> s = 'Hello, World!' >>> s.find('World') 7 >>> s[7] 'W' >>> s.find('Universe') -1
Этот метод имеет два необязательных аргумента start и end . Если их указать, то поиск будет осуществляться в срезе строки s[start:end] :
>>> s 'Hello, World!' >>> s.find('o') 4 >>> s[3:6] 'lo,' >>> s.find('o', 7) 8 >>> s[7:10] 'Wor'
И, как видно, str.find осуществляет поиск первого вхождения подстроки, начиная слева.
Чтобы осуществить поиск подстроки, начиная справа (т.е. с конца) строки, можно воспользоваться методом str.rfind . Сравните:
>>> s 'Hello, World!' >>> s.rfind('o') 8 >>> s.find('o') 4
Метод str.rfind имеет тот же интерфейс, что и str.find : он имеет два необязательных аргумента, чтобы задать диапазон поиска и возвращает -1, если подстрока не найдена.
Подсчёт
Методом str.count можно подсчитать количество вхождений подстроки в строку:
>>> s = 'Пингвины не любят окна.' >>> s.count('а') 1 >>> s.count('ин') 2 >>> s.count('яблоки') 0
Диапазон поиска можно указать так же, как в str.find .
Замена
Для замены подстроки в строке существует метод str.replace :
>>> src = 'Пингвины не любят окна.' >>> replaced = src.replace('Пингвины', 'Даже окна') >>> src 'Пингвины не любят окна.' >>> replaced 'Даже окна не любят окна.'
Так как строки в Python неизменяемые, то str.replace на базе исходной строки создает и возвращает новую.
У этого метода есть дополнительный параметр - количество производимых замен. Если этот параметр выставлен в -1 (значение по умолчанию), то произойдёт замена всех вхождений.
>>> s = 'aaaaa' >>> s.replace('a', 'b') 'bbbbb' >>> s.replace('a', 'b', 3) 'bbbaa'
Разбиение и объединение
По существу, вы уже знакомы с этими операциями и применяли их.
Можно разбивать строку на основе подстроки с помощью str.split . Результатом этой операции является список. Например, может стоять задача по разбиению предложения на слова:
>>> sentence = 'Пингвины не любят окна.' >>> sentence.split() ['Пингвины', 'не', 'любят', 'окна.'] >>> sentence2 = 'вставка, выбор, пузырёк, подсчёт, Хоар, слияние' >>> sentence2.split(', ') ['вставка', 'выбор', 'пузырёк', 'подсчёт', 'Хоар', 'слияние']
В первом случае в качестве подстроки для разбиения используется значение по умолчанию: разбиение по символам, обозначающих пустое пространство (пробелы, табуляция, перенос строки). Во втором случае разбиение задано явно - по подстроке ', ' .
>>> sentence3 = 'вставка -- выбор -- пузырёк -- подсчёт -- Хоар -- слияние' >>> sentence3.split() ['вставка', '--', 'выбор', '--', 'пузырёк', '--', 'подсчёт', '--', 'Хоар', '--', 'слияние'] >>> sentence3.split('--') ['вставка ', ' выбор ', ' пузырёк ', ' подсчёт ', ' Хоар ', ' слияние'] >>> sentence3.split(' -- ') ['вставка', 'выбор', 'пузырёк', 'подсчёт', 'Хоар', 'слияние']
У str.split есть ещё один необязательный аргумент - количество разбиений.
Итак, str.split разбивает строку по подстроке и возвращает список строк. Обратная операция это объединение массива строк в одну строку, она осуществляется с помощью str.join :
>>> sentence3 = 'вставка -- выбор -- пузырёк -- подсчёт -- Хоар -- слияние' >>> sort_algs = sentence3.split(' -- ') >>> sort_algs ['вставка', 'выбор', 'пузырёк', 'подсчёт', 'Хоар', 'слияние'] >>> ''.join(sort_algs) 'вставкавыборпузырёкподсчётХоарслияние' >>> ' '.join(sort_algs) 'вставка выбор пузырёк подсчёт Хоар слияние' >>> ' + '.join(sort_algs) 'вставка + выбор + пузырёк + подсчёт + Хоар + слияние'
Этот метод более гибкий для входных данных и позволяет объединять не только список строк, но и любой другой итерируемый объект. Главное, чтобы этот объект содержал только строки:
>>> ' '.join(range(10)) Traceback (most recent call last): File "", line 1, in TypeError: sequence item 0: expected str instance, int found >>> ' '.join(map(str, range(10))) '0 1 2 3 4 5 6 7 8 9'
Префикс-функция, алгоритм Кнута-Морриса-Пратта, Z-функция
Описание алгоритмов вы можете найти по ссылке.
Контест №12
Ссылки на контесты
- Начинающие (участвовать)
- Основные (участвовать)
- Продвинутые (участвовать)
Сайт построен с использованием Pelican. За основу оформления взята тема от Smashing Magazine. Исходные тексты программ, приведённые на этом сайте, распространяются под лицензией GPLv3, все остальные материалы сайта распространяются под лицензией CC-BY.
Как на python организовать сравнение двух строк?
Вообще, зависит от того, что вы имеете в виду под точностью. Есть модуль strsimpy для сравнения строк, в том числе там например реализованы разные вариации расстояния Левенштейна. Также см. модуль fuzzywuzzy
20 мая 2022 в 6:26
Может хватит точности от библиотеки difflib
20 мая 2022 в 11:46
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Думаю можно попробовать что такого вида, если вы хотите проверять на сколько процентов одна строка входит в другую
s = "hello world how are you doing" a = "doing" mn_string, mx_string = (s, a) if len(s) < len(a) else (a, s) for i in range(len(mn_string)-1, -1, -1): if mn_string[:i+1] in mx_string: coincidences = i+1 break print(coincidences*100/ len(mx_string)) # 17.24137931034483
но это не будет работать в случае если обе строки будут содержать по несколько слов и важно что слова могут стоять на разных местах например:
# тут сработает верно, ответ около 48 s = "My name is Dima" a = "is Dima" # тут сработает неверно, ответ будет 0 s = "My name is Dima" a = "They call me Dima"
Сравнение строк
Строка в Python – это набор символов, находящийся в кавычках. Язык программирования позволяет проводить операции сравнения строк, для этого используются следующие операторы: , >=. Сравнение строк имеет ряд своих особенностей, отличающихся от сравнения чисел.
Больше / Меньше
Сравнение больше или меньше выполняется с помощью операторов > и < соответственно. Например, сравним строки со словом apple и banana:
print("apple" > "banana") False
print("apple" < "banana") True
Логично предположить, что apple находится перед banana, а буква «a» идет перед «b», что и дает такой результат. Но на деле все несколько сложнее. Проверим равенство apple и Apple:
print("apple" == "Apple") False
print("apple" > "Apple") True
Дело в том, что одинаковые буквы в разных регистрах считаются разными символами. Компьютер различает символы по присвоенным им уникальным значениям. В нашем случае, латинская «A» имеет значение 65, строчная «a» – 97. Узнать уникальное значение любого символа можно с помощью функции ord. Например:
print(ord("A")) 65
При сравнении символов или строк, Python конвертирует символы в их соответствующие порядковые значения, после чего сравнивает слева направо. В примере выше «a» больше чем «A», соответственно «apple» больше чем «Apple».
Существует функция chr, преобразовывающая порядковое значение в символ. Пример:
print(chr(1040)) А
В результате будет кириллическая А, которой соответствует значение 1040. Свои значения имеют не только буквы и цифры, но и вспомогательные знаки, вроде ? или =. Пробел » » также имеет свое значение – 32.
Человек обычно игнорирует разницу между регистрами букв, но компьютер так не делает. Решается это простой конвертацией строки в стандартный формат, например, в нижний регистр, после чего можно производить сравнение.
str1 = "apple" str2 = "Apple" str2.lower() print(str1 == str1) True
В данном примере сравнения строк в Python 3, мы привели str2 к нижнему регистру с помощью метода lower. Поэтому результатом сравнения является True.
Равенство
Проверить равенство срок можно с помощью оператора == . Например:
print("строка1" == "строка2") False
Таким образом, выполняется точное сравнение в Python. Данные две строки не равны, поэтому результат равен False.
Иногда возникает ситуация, когда две строки содержат одинаковые символы, но они переставлены местами. Понятно что такие строки будут не равны. Если нужно сделать проверку, на то, что символы в строках одинаковые, но просто переставлены местами, то можно поступить следующим способом.
Превратить строку в список и отсортировать. Проверяем результат сравнения и выводим содержимое отсортированных списков.
strA = "abcde" strB = "abdec" print(sorted(list(strA)) == sorted(list(strB))) print(sorted(list(strA))) print(sorted(list(strB))) True ['a', 'b', 'c', 'd', 'e'] ['a', 'b', 'c', 'd', 'e']
Не равно
Оператор != проверяет, верно ли то, что строки не равны. Например:
print("abc" != "zxc") True
Поскольку abc не равняется zxc.
Больше или равно / Меньше или равно
Операторы = определяют, верно ли утверждение, что одна строка больше/меньше или равна другой. Проще говоря, если выполняется хотя бы одно условие, то будет True. Например:
print("abc"
Поскольку abc меньше чем bcd.
print("abc" >= "abc") True
Поскольку обе строки равны.
