Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Генераторы множеств и словарей Python: Декларативное программирование

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

Уже из этого множества легко получить словарь, применив функцию dict(). Кажется, что с помощью генераторов списков мы можем описывать словари и множества так же декларативно, как и списки.

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

Python и здесь приходит нам на помощь. Он предоставляет генераторы множеств и генераторы словарей, которые мы изучим в этом уроке.

Генераторы множеств

С этими генераторами все максимально просто. Нужно всего два действия:

  • Взять выражение, описывающее генератор списка
  • Заменить в нем квадратные скобки на фигурные

Посмотрим, как это работает:

squares = {x * x for x in range(10)}
squares
# {0, 1, 64, 4, 36, 9, 16, 49, 81, 25}
5 * 5 in squares
# True

Вы получаете все те же возможности, которые доступны для генерации списков. Есть и дополнительное преимущество — при создании множества можно еще и проследить за тем, чтобы в список не попали дубли. Так можно сэкономить память.

Генераторы словарей

Генераторы словарей выглядят очень похоже на генераторы множеств. Разница заключается в том, как описывается элемент словаря.

Нужно сгенерировать не только значение, но и ключ. При этом ключ надо указать через двоеточие — так же, как при написании литерала словаря.

Посмотрим на примере:

char_positions = {char: pos for pos, char in enumerate("Hello, World!")}
char_positions
# {'H': 0, 'e': 1, 'l': 10, 'o': 8, ',': 5, ' ': 6, 'W': 7, 'r': 9, 'd': 11, '!': 12}
char_positions['o']
# 8

Обратите внимание, что в этом примере ключ 'l'имеет значение 10. Посмотрим, какие значения имели char и pos во время генерации. Для простоты будем смотреть только на позиции символа 'l':

[(char, pos) for pos, char in enumerate("Hello, World!") if char == 'l']
# [('l', 2), ('l', 3), ('l', 10)]

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

char_positions = {}
for pos, char in enumerate("Hello, World!"):
    char_positions[char] = pos

char_positions
# {'H': 0, 'e': 1, 'l': 10, 'o': 8, ',': 5, ' ': 6, 'W': 7, 'r': 9, 'd': 11, '!': 12}

В примере выше порядок ключей получается тот же самый — это порядок первого появления соответствующего символа в строке. Последующие перезаписи значений этот порядок не изменят. Словари в Python запоминают порядок добавления ключей, но не порядок последующих изменений значений.

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


Дополнительные материалы

  1. Генераторы множеств и словарей

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Django
10 месяцев
с нуля
Старт 2 мая

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»