У цьому матеріалі ми розглянемо, як за допомогою мови програмування Python розв’язувати поширені задачі, пов’язані з обробкою текстових даних.
Зокрема, ви навчитеся ідентифікувати, чи є певні рядки паліндромами, анаграмами, а також визначати, чи відповідає їхній регістр формату “заголовкового” написання.
Рядки у Python: Короткий огляд
У Python рядки є вбудованим типом даних, який має значну функціональність. Вони використовуються для зберігання послідовності символів.
Індексування рядків: Подібно до інших ітерованих об’єктів у Python, рядки мають індексацію, що починається з нуля. Це означає, що для рядка довжиною N, допустимі індекси варіюються від 0, 1, 2 і так далі до N – 1.
Python також підтримує можливість доступу до елементів з кінця рядка, використовуючи від’ємні індекси. Таким чином, індекс -1 вказує на останній символ, -2 – на передостанній і так далі.
Незмінність рядків у Python: Важливо відзначити, що рядки в Python є незмінними. Це означає, що після створення рядка ви не можете змінювати його безпосередньо. Однак, ви можете використовувати різноманітні методи рядків для отримання нових рядків з потрібними змінами.
Тепер, коли ми ознайомилися з базовими поняттями про рядки в Python, перейдемо до розгляду кількох простих, але цікавих завдань.
Розпочнімо.
Перевірка, чи є рядок у Python паліндромом
Завдання: Маючи рядок у Python, необхідно визначити, чи є він паліндромом.
У разі позитивної відповіді, функція повинна повернути True, інакше – False.
Отже, перша задача полягає у визначенні, чи є даний рядок паліндромом.
Паліндром – це текстова послідовність, яка читається однаково зліва направо і справа наліво. Наприклад: “радар”, “мадам”, “рівень”, “ротатор”.
Алгоритм для розв’язання цієї задачі включає наступні кроки:
- Створити перевернуту копію вхідного рядка, за необхідності зберігаючи її в окремій змінній.
- Порівняти початковий рядок з його перевернутою версією.
- Якщо обидва рядки ідентичні, це означає, що вхідний рядок є паліндромом. У такому випадку потрібно повернути True і завершити виконання.
- Якщо початковий рядок не збігається зі своєю перевернутою копією, то він не є паліндромом. В такому випадку потрібно повернути False.
Ключовим етапом є створення перевернутої копії. У Python це можна зробити різними способами.
Розглянемо два основні методи:
- Використання зрізів рядків
- Застосування функції reversed() у поєднанні з методом join()
Перевертання рядка у Python за допомогою зрізів
Синтаксис
- Якщо параметр start не вказано, то зріз починається з початку рядка.
- Якщо параметр stop не вказано, то зріз продовжується до кінця рядка.
- Від’ємні значення step дозволяють обходити рядок у зворотному напрямку.
Отже, вираз
У наступному кодовому блоці представлено визначення функції is_palindrome(), яка приймає рядок як вхідний параметр і повертає True або False залежно від того, чи є цей рядок паліндромом.
У цій функції для створення перевернутої копії рядка використано зрізи рядків.
def is_palindrome(this_str): rev_str = this_str[::-1] if (this_str == rev_str): return True else: return False
▶️ Тепер, коли функцію визначено, можна викликати її з будь-яким допустимим рядком як аргументом.
is_palindrome("racecar") True
У наведеному вище прикладі рядок “racecar” є паліндромом. Тому функція is_palindrome() повертає True, як і очікувалося.
Спробуємо викликати функцію з рядком, який не є паліндромом, наприклад, “river”.
is_palindrome("river") False
Як бачимо, функція повертає False, що є правильним результатом. ✅
Перевертання рядка у Python за допомогою reversed() та join()
У Python для перевертання рядка можна використовувати метод join() у поєднанні з функцією reversed().
- Функція reversed() створює ітератор у зворотному порядку для символів у рядку.
- Метод join() використовується для з’єднання цих символів у зворотній послідовності.
Використовуючи описаний підхід, функцію is_palindrome() можна переписати наступним чином, як показано в кодовому блоці нижче.
def is_palindrome(this_str): rev_str="".join(reversed(this_str)) if (this_str == rev_str): return True else: return False
Функцію is_palindrome() також можна застосувати всередині генератора списку для фільтрування паліндромів з набору рядків.
str_list = ["refer","blue","level","12321","dragon"] palindromes = [string for string in str_list if is_palindrome(string)] print(palindromes) # Output ['refer', 'level', '12321']
Пояснення наведеного вище коду:
- Проходимо через кожен рядок у списку str_list і викликаємо функцію is_palindrome().
- Якщо функція is_palindrome() повертає True, то рядок додається до списку palindromes.
Як видно у виводі, palindromes – це список, що містить всі паліндромні рядки з str_list.
Перевірка, чи є два рядки в Python анаграмами
Ще одне поширене завдання, яке може виникнути під час співбесіди, – це визначити, чи є два рядки, str1 та str2, анаграмами.
Два рядки вважаються анаграмами, якщо вони складаються з абсолютно ідентичної кількості однакових символів. Це означає, що один рядок можна отримати, переставляючи символи іншого рядка.
Приклади анаграм: “ніч – чін”, “літо – тіло”, “кот – ток”.
Перевірка наявності анаграм за допомогою об’єкта Counter у Python
Простий та зрозумілий спосіб – це підрахувати кількість входжень кожного символу в обох рядках, а потім перевірити, чи збігаються ці підрахунки.
Це можна спростити, використовуючи об’єкт Counter з модуля itertools. Об’єкт Counter повертає словник Python, де ключами є символи, а значеннями – відповідні кількості їх входжень.
Розглянемо, наприклад, рядки “save” та “vase”, як показано нижче.
str1 = "save" str2 = "vase"
Тут c1 та c2 – це об’єкти Counter, що містять частоту входження символів рядків str1 та str2 відповідно.
from collections import Counter c1 = Counter(str1) c2 = Counter(str2) print(c1) print(c2) c1 == c2 # Output Counter({'s': 1, 'a': 1, 'v': 1, 'e': 1}) Counter({'v': 1, 'a': 1, 's': 1, 'e': 1}) True
Вираз c1 == c2 повертає True, оскільки str1 та str2 є анаграмами.
Використовуючи цю логіку, можна визначити функцію are_anagrams() з двома параметрами, word1 та word2. У тілі функції ми перевіряємо, чи Counter(word1) == Counter(word2).
def are_anagrams(word1, word2): if Counter(word1) == Counter(word2): return True else: return False
▶️ Для перевірки викличемо are_anagrams() з str1 та str2 як аргументами. Оскільки str1 та str2 є анаграмами (“save” та “vase”), функція поверне True, що є правильним результатом.
are_anagrams(str1, str2) True
Перевірка анаграм за допомогою відсортованих копій рядків
Існує ще один спосіб перевірити, чи є рядки анаграмами.
Якщо два рядки є анаграмами, їх відсортовані копії будуть ідентичними.
Тому ми можемо переписати функцію are_anagrams() і перевірити, чи збігається відсортована версія str1 з відсортованою версією str2. Якщо вони рівні, то рядки є анаграмами, інакше – ні.
Використовуючи наведений підхід, функцію are_anagrams() можна переписати наступним чином.
def are_anagrams(word1, word2): if sorted(word1) == sorted(word2): return True else: return False
Тепер зробимо кілька викликів функції.
- Рядки “elbow” та “below” є анаграмами, тому функція are_anagrams() повертає True.
- Рядки “state” та “tasted” не є анаграмами, і функція повертає False.
are_anagrams("below","elbow") True are_anagrams("state","tasted") False
Перевірка, чи рядок у Python має “заголовковий” регістр
Ось наше останнє завдання в цьому матеріалі.
Завдання. Задано рядок, що представляє ім’я особи (ім’я та прізвище).
Необхідно перевірити, чи написана перша літера імені та прізвища у верхньому регістрі.
Такий формат написання, коли перша літера кожного слова є великою, називається “заголовковим” регістром.
Тому потрібно визначити, чи відповідає ім’я “заголовковому” регістру:
1. У разі позитивної відповіді, потрібно вивести повідомлення про те, що рядок уже відформатовано у “заголовковому” регістрі.
2. У іншому випадку, потрібно повернути копію рядка, відформатовану у “заголовковому” регістрі.
- Python має вбудований метод string istitle(), який перевіряє, чи рядок відповідає “заголовковому” регістру.
- Метод Python title() повертає копію рядка, відформатовану в “заголовковому” регістрі.
Тепер можна використати ці два методи для розв’язання задачі.
Визначимо функцію check_titlecase(), яка приймає ім’я як аргумент.
- Використаємо метод istitle() для перевірки, чи вхідний рядок відформатовано у “заголовковому” регістрі.
- Якщо повертається True, то виводимо повідомлення, що рядок вже має “заголовковий” регістр.
- У іншому випадку, використовуємо метод title() і повертаємо копію рядка, відформатовану у “заголовковому” регістрі.
У наступному кодовому блоці показано визначення функції check_titlecase().
def check_titlecase(name): if name.istitle(): print(f"'{name}' is already formatted in title case.") else: return name.title()
Тепер викличемо метод check_titlecase() з аргументом.
check_titlecase("jane smith") # Output Jane Smith
У виводі вище можна побачити, що рядок “jane smith” тепер відформатований у “заголовковому” регістрі.
▶️ Розглянемо інший приклад.
check_titlecase("agatha Christie") # Output Agatha Christie
Тепер викличемо функцію з рядком, який вже відформатований у “заголовковому” регістрі.
check_titlecase("Grace Hopper") # Output 'Grace Hopper' is already formatted in title case.
Ми отримали повідомлення про те, що рядок вже відформатовано у “заголовковому” регістрі, отже, функція працює коректно.
Висновок 👩🏫
Підсумуємо завдання, які ми розглянули:
- Щоб перевірити, чи рядок є паліндромом, необхідно перевірити, чи збігається рядок зі своєю перевернутою версією. Для перевертання рядка можна використовувати зрізи або вбудовані методи.
- Для визначення, чи є два рядки анаграмами, необхідно перевірити, чи однакові їхні відсортовані копії. Для сортування рядка використовуйте вбудовану функцію sorted().
- Щоб перевірити, чи ім’я написане у “заголовковому” регістрі, використовуйте метод .istitle() для перевірки, та метод .title() для отримання копії рядка з “заголовковим” регістром.
Сподіваємося, вам сподобався цей огляд задач обробки рядків у Python. У якості наступного кроку можете вивчити генератори списків у Python або ознайомитися з оператором нерівності.
Вдалого вам навчання та програмування!🎉