Индекс, значение и enumerate()
for умеет перебирать не только числа — а счётчик и накопитель превращают простой перебор в настоящий инструмент анализа данных.
for умеет перебирать не только числа
Строка — это последовательность символов (глава 8), а значит, for
умеет перебирать и её — символ за символом, без индексов:
for letter in "Python":
print(letter)
То же самое работает для списков и любых других итерируемых объектов —
так называют всё, что for умеет перебирать по одному элементу.
Строка, список, диапазон range() — всё это итерируемые объекты;
точный технический механизм, как именно Python это делает «под капотом», мы разберём в
следующих главах, когда будем подробно изучать списки.
Индекс против значения
В цикле for letter in "Python": мы получаем сам символ
(«значение»), но не его номер по счёту («индекс»). Иногда номер важен — например, чтобы
вывести «символ №1: P».
Классический вариант — цикл по индексам
slovo = "Python"
for i in range(len(slovo)):
print(i, slovo[i])
«Питонический» вариант — enumerate()
slovo = "Python"
for i, letter in enumerate(slovo):
print(i, letter)
| i | letter |
|---|---|
| 0 | P |
| 1 | y |
| 2 | t |
| 3 | h |
| 4 | o |
| 5 | n |
enumerate() нужен именно тогда, когда важны и индекс, и значение одновременно. Если индекс вообще не нужен — используйте for letter in slovo:, без него. Цикл по индексам (range(len(...))) — не «неправильный» способ, а просто более многословный там, где enumerate() справится короче.Счётчик — переменная, которая считает
Счётчик — переменная, которая с каждой итерацией увеличивается (или уменьшается) на фиксированный шаг, обычно на 1. Она отслеживает «сколько раз мы это уже сделали».
glasnye = "аеёиоуыэюя"
slovo = "программирование"
kolichestvo = 0
for letter in slovo:
if letter in glasnye:
kolichestvo += 1
print(kolichestvo)
| Символ | letter in glasnye? | kolichestvo после шага |
|---|---|---|
| п | нет | 0 |
| р | нет | 0 |
| о | да | 1 |
| г | нет | 1 |
| р | нет | 1 |
| а | да | 2 |
| … | … | … |
Накопитель (аккумулятор) — переменная, которая копит результат
Накопитель устроен похоже на счётчик, но копит не количество шагов, а сам результат — сумму, произведение, склеенную строку:
chisla = [4, 8, 15, 16, 23, 42]
summa = 0
for n in chisla:
summa += n
print(summa)
| Итерация | n | summa после шага |
|---|---|---|
| 1 | 4 | 4 |
| 2 | 8 | 12 |
| 3 | 15 | 27 |
| 4 | 16 | 43 |
| 5 | 23 | 66 |
| 6 | 42 | 108 |
kolichestvo = 0) — без этого шага kolichestvo += 1 на первой же итерации упадёт с ошибкой, потому что переменной ещё не существует.Мини-проект: анализатор текста
Соберём счётчик и накопитель вместе в одном небольшом инструменте — подсчитаем гласные, длину самого длинного слова и общее число слов в тексте:
tekst = "python это просто и понятно"
slova = tekst.split()
glasnye_count = 0
for letter in tekst:
if letter in "аеёиоуыэюя":
glasnye_count += 1
samoe_dlinnoe = ""
for slovo in slova:
if len(slovo) > len(samoe_dlinnoe):
samoe_dlinnoe = slovo
print(f"Слов: {len(slova)}, гласных: {glasnye_count}, самое длинное: {samoe_dlinnoe}")
glasnye_count и samoe_dlinnoe — два разных накопителя, каждый со своим циклом и своей начальной инициализацией. Комбинировать несколько состояний в одной программе — обычное дело, главное — не запутать, какое состояние меняется в каком цикле.