Рядки трапляються дитині раніше за будь-які інші дані: перша ж програма щось друкує, друга щось запитує. Але працювати з ними всерйоз починають пізніше, і тоді з'ясовується, що рядок уміє значно більше, ніж просто виводитися на екран.

Нижче довідник по тому, що справді використовується: як дістати частину рядка, які методи потрібні в задачах, як зібрати текст із чисел і чому спроба змінити одну букву закінчується помилкою. Приклади короткі — їх зручно набрати й одразу подивитися результат.

Рядок — це послідовність

До кожного символу можна звернутися за номером, так само як до елемента списку. Нумерація з нуля, від'ємні номери рахуються з кінця.

slovo = 'Python'
print(slovo[0])     # P
print(slovo[-1])    # n
print(slovo[1:4])   # yth
print(slovo[::-1])  # nohtyP
print(len(slovo))   # 6

Зрізи працюють так само, як у списках: права межа не входить, тому [1:4] дає три символи. Запис [::-1] перевертає рядок — найкоротший спосіб перевірити, чи є слово паліндромом, і один з перших трюків, який діти переписують один в одного.

Методи, які потрібні насправді

МетодЩо робитьПриклад результату
upper()усі великіPYTHON
lower()усі маліpython
capitalize()перша великаPython
strip()прибирає пробіли по краяхтекст без відступів
replace(a, b)замінює всі входженняновий рядок
split()ріже на список слівсписок
join(spysok)склеює список у рядокрядок
find(a)номер символу або -1число
count(a)скільки разів зустрілосячисло
startswith(a)чи починається зTrue або False
isdigit()чи складається з цифрTrue або False

Два останні рядки корисніші, ніж здаються. Перевірка isdigit() дозволяє запитати в користувача число і не впасти, якщо він ввів слово: спочатку перевіряємо, потім перетворюємо. Без неї перша ж програма з вводом падає, щойно хтось натисне Enter не ту клавішу.

Метод find() відрізняється від схожого index() однією деталлю: коли нічого не знайдено, перший тихо повертає мінус одиницю, а другий зупиняє програму помилкою. Для перевірки «чи є таке взагалі» надійніше взяти in: запис 'a' in slovo читається краще за обидва.

f-рядки: складання тексту з чисел

Найзручніший спосіб зібрати повідомлення — поставити перед лапками літеру f і вписати змінні прямо в текст, у фігурних дужках.

imia = 'Olia'
ochky = 120
print(f'{imia} набрала {ochky} балів')
print(f'Середнє: {ochky / 7:.2f}')

Другий рядок показує заодно форматування: двокрапка й .2f означають «показати два знаки після коми». Без цього ділення дає довгий хвіст цифр, який у звіті виглядає неохайно.

До f-рядків текст збирали плюсом, і цей спосіб досі зустрічається в старих підручниках. Проблема в тому, що плюс не вміє складати текст із числом: 'Балів: ' + 120 дає помилку, і доводиться писати str(120) навколо кожного числа. З f-рядком перетворення відбувається само.

Рядок не можна змінити

Ось головна несподіванка теми. Спроба замінити один символ на місці не працює взагалі:

slovo = 'Python'
slovo[0] = 'J'    # помилка
slovo = 'J' + slovo[1:]   # а так правильно

Рядки в Python незмінні: будь-який метод не править наявний, а повертає новий. Тому запис slovo.upper() сам по собі нічого не змінює — результат треба кудись покласти, хоча б назад у ту саму змінну. Це найчастіша причина, через яку «метод не спрацював»: він спрацював, просто результат нікуди не записали.

Списки в цьому влаштовані навпаки, і дитині корисно побачити обидва випадки поруч: тоді правило запам'ятовується як відмінність, а не як окремий факт про рядки.

input завжди дає текст

Ще одне місце, де програма падає на рівному місці. Усе, що введено з клавіатури, приходить рядком, навіть якщо це цифри.

vik = input('Скільки тобі років? ')
print(vik + 1)        # помилка
print(int(vik) + 1)   # працює

Перетворення int() потрібне кожного разу, коли введене збираються рахувати. Якщо число дробове, береться float(). А якщо користувач ввів слово, int() теж падає — і саме тут стає в пригоді згаданий вище isdigit().

Перебір рядка циклом

Рядок перебирається так само, як список, і це той момент, коли дві теми нарешті сходяться. Цикл проходить по символах, а не по словах, і цього вистачає для більшості навчальних задач.

slovo = 'programuvannia'
holosni = 'aeiouyаеєиіїоуюя'
lichylnyk = 0

for bukva in slovo:
    if bukva in holosni:
        lichylnyk = lichylnyk + 1

print(lichylnyk)

Задача про підрахунок голосних виглядає шкільною, але всередині неї три важливі речі одразу: перебір, перевірка на входження і накопичувач. Тому ми ставимо її в програму саме після рядків — вона збирає докупи те, що доти існувало окремо.

Якщо потрібен не сам символ, а його номер, зручніше enumerate: він віддає пару «номер і символ» за один прохід, і не доводиться вести окрему змінну-лічильник.

Довгий текст і перенос рядка

Для багаторядкового тексту беруть три лапки замість одної. Усе, що всередині, зберігається як є, разом з переносами:

pravyla = '''Правила гри:
1. Три спроби
2. Підказка коштує бал'''
print(pravyla)

Другий спосіб — спеціальна пара символів усередині звичайного рядка, яка означає перехід на новий рядок. Виглядає вона як зворотна скісна риска з буквою n, і саме через неї найчастіше виникає плутанина: у тексті її видно двома символами, а на екрані вона перетворюється на перенос.

Для дитини корисно одразу пояснити, що це не помилка друку, а команда всередині тексту. Поруч живуть ще дві такі ж: табуляція і сама зворотна скісна риска, яку, щоб надрукувати, доводиться писати двічі.

split і join: туди й назад

Ці два методи ходять парою і разом вирішують більшість задач з текстом. Перший розрізає рядок на список, другий збирає список назад у рядок.

rechennia = 'kit sydyt na vikni'
slova = rechennia.split()        # список з чотирьох слів
print(len(slova))                # 4
print(' '.join(slova[::-1]))     # слова у зворотному порядку

Без аргументів split() ріже по будь-яких пробілах, і зайві пробіли між словами його не бентежать. Можна вказати, по чому різати: split(',') розбере рядок з комами, і саме так читають прості таблиці.

Запис ' '.join(slova) спочатку виглядає перевернутим: роздільник стоїть попереду, а список у дужках. Логіка в тому, що склеює саме роздільник, і це той рідкісний випадок, коли пояснення «так вирішили» працює гірше, ніж просто запам'ятати форму.

Одна задача цілком

Щоб методи перестали бути переліком, корисно скласти з них щось робоче. Класична задача — порахувати, скільки разів кожне слово зустрічається в тексті. Вона коротка, і в ній працює все одразу: приведення регістру, різання на слова, словник як накопичувач.

tekst = 'Kit sydyt. Kit spyt. Sobaka bihaie.'
slova = tekst.lower().replace('.', ' ').split()
chastota = {}

for slovo in slova:
    chastota[slovo] = chastota.get(slovo, 0) + 1

print(chastota)

Другий рядок варто розібрати окремо: методи викликаються ланцюжком, зліва направо. Спочатку все стає малими літерами, потім крапки замінюються пробілами, і тільки після цього рядок ріжеться на слова. Поміняти порядок — і крапка приклеїться до слова, а kit і Kit порахуються як різні.

Саме тут видно, навіщо був потрібен get зі словників: без нього перше ж нове слово зупинило б програму помилкою.

Три помилки, які повторюються

Перша: slovo.replace('a', 'o') написано окремим рядком, а результат нікуди не збережено. Виглядає як «метод не працює».

Друга: порівняння з різним регістром. Рядок 'Так' не дорівнює 'так', і вікторина не зараховує правильну відповідь. Лікується приведенням обох сторін до нижнього регістру перед порівнянням.

Третя: невидимі пробіли. Відповідь, скопійована з іншого місця, часто приходить з пробілом на кінці, і порівняння провалюється без видимої причини. Звичка писати .strip() одразу після input() знімає цю проблему назавжди.

Рядки добре лягають поруч зі списками — їх довідник тут, а перебирати і те, і те зручно циклом for. Що ламається в перших програмах найчастіше, зібрано в типових помилках новачків.