Итерация

Что общего имеют список [1, 2, 3], строка 'Привет, мир!' и словарь {'title': 'Killfish', 'seats': 120}? Если вы ответили «это всё итерируемые объекты», то вам эта статья будет неинтересна, потому что вы правы.

Доступ к элементам списков, строк и словарей можно получить с помощью специального синтаксиса. О нём и пойдет речь в этой статье.

Проблема

В программировании много задач, которые требуют проводить одинаковые операции раз за разом: вывести числа от 1 до 10, посчитать статистику продаж, найти кратчайший путь к бару. Для решения этих задач используют итерацию.

Итерация — это когда мы последовательно, один за другим, получаем элементы коллекции. Коллекция — это списки, словари и прочие структуры, в которых содержатся интересные нам данные (например, дистанции до баров). Прелесть итерации в том, что не нужно запоминать устройство коллекции. Итерация по списку ничем не отличается от итерации по словарю.

Итерация по списку

В других языках список называют массивом, а элементы в нём обходят так:

for(int i = 0; i < books_amount; i++) {
    cout << books[i];
}

Поэтому когда новички приходят писать на Python, они делают

for i in range(len(books)):
    print(books[i])

Здесь есть проблема: вводится вспомогательная переменная i. Короткое бессмысленное название переменной означает, что она не нужна с точки зрения бизнес-логики. В Python от неё легко избавиться:

for book in books:
    print(book)

Бывает, что мы хотим вывести не только название книги, но и её порядковый номер. И хочется написать так

book_number = 0
for book in books:
    print(book_number, book)
    book_number += 1

Но зачем проставлять номера вручную, можно же попросить Python сделать это за нас:

for book_number, book in enumerate(books):
    print(book_number, book)

Так и выглядит итерация в Python:

for element in collection:
    # do something

Итерация по строке

Этот код выводит «Привет, мир» в столбик:

phrase = 'Привет мир!'
for character in phrase:
    print(character)

Результат был бы таким же, если бы мы сделали

phrase = ['П', 'р', 'и', 'в', 'е', 'т', 'м', 'и', 'р', '!']
for character in phrase:
    print(character)

Всё потому, что строка — это тоже итерируемый объект.

Итерация по словарю

Положим, у нас есть бар:

my_bar = {
    'title': 'Killfish',
    'seats': 120,
    'address': 'Ул. Пушкина, д. Колотушкина',
    'average_rating': 4.1,
}

Проитерируем по нему:

for element in my_bar:
    print(element)

Получим:

title
seats
address
average_rating

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

for element in my_bar:
    print(element, my_bar[element])

Или лучше

for characteristic, value in my_bar.items():
    print(characteristic, value)

Разберите пример ниже самостоятельно. Что делают методы keys() и values и items()?

Итог

Итак, чтобы получить элементы коллекции, мы используем синтаксис

for element in collection:
    # do something

Его стоит предпочитать всех ситуациях. Даже когда нам нужны номера, не стоит вычислять их вручную:

for element_number, element in enumerate(collection):
    # do something

О том, как работает синтаксис for … in ... под капотом, мы рассказываем в статье «Как устроены итераторы».