Dict и set comprehensions

Dict и set comprehensions

В модуле 5 вы изучили list comprehensions — компактный способ создавать списки по формуле. Python поддерживает аналогичный синтаксис для словарей и множеств. Эти инструменты позволяют писать краткий и выразительный код для создания и трансформации коллекций.

Dict comprehension

Синтаксис:

{ключ_выражение: значение_выражение for переменная in итерируемое}

Простой пример — создать словарь «слово → длина слова»:

words = ["apple", "banana", "cherry"]
lengths = {word: len(word) for word in words}
print(lengths)   # {'apple': 5, 'banana': 6, 'cherry': 6}

Без comprehension это выглядело бы так:

lengths = {}
for word in words:
    lengths[word] = len(word)

Трансформация значений

Dict comprehension удобен для преобразования существующего словаря:

prices = {"яблоко": 50, "банан": 30, "вишня": 80}

# Удвоить все цены:
doubled = {item: price * 2 for item, price in prices.items()}
print(doubled)   # {'яблоко': 100, 'банан': 60, 'вишня': 160}

# Скидка 10%:
discounted = {item: round(price * 0.9) for item, price in prices.items()}
print(discounted)

# Инвертировать словарь (значение → ключ):
inverted = {v: k for k, v in prices.items()}
print(inverted)   # {50: 'яблоко', 30: 'банан', 80: 'вишня'}

Инверсия работает корректно только если все значения уникальны. При дубликатах останется последняя пара.

Фильтрация в dict comprehension

Добавьте if для фильтрации:

prices = {"яблоко": 50, "банан": 30, "вишня": 80, "манго": 200}

# Только дорогие (больше 60):
expensive = {item: price for item, price in prices.items() if price > 60}
print(expensive)   # {'вишня': 80, 'манго': 200}

# Оценки с переводом:
scores = {"Алиса": 92, "Борис": 55, "Вера": 78, "Гриша": 45}
passed = {name: score for name, score in scores.items() if score >= 60}
print(passed)   # {'Алиса': 92, 'Вера': 78}

Set comprehension

Синтаксис:

{выражение for переменная in итерируемое}

Похоже на list comprehension, но в фигурных скобках — и результат без дубликатов:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Квадраты:
squares = {x ** 2 for x in numbers}
print(squares)   # {1, 4, 9, 16, 25, 36, 49, 64, 81, 100}

# Уникальные длины слов:
words = ["cat", "dog", "elephant", "ant", "bee"]
lengths = {len(w) for w in words}
print(lengths)   # {3, 8} (порядок не гарантирован)

Фильтрация в set comprehension

data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_squares = {x ** 2 for x in data if x % 2 == 0}
print(even_squares)   # {4, 16, 36, 64, 100}

Практические примеры

Создание частотного словаря:

text = "в начале было слово и слово было у бога"
words = text.split()
freq = {word: words.count(word) for word in set(words)}   # set(words) — уникальные
print(freq)
# {'бога': 1, 'было': 2, 'в': 1, 'и': 1, 'начале': 1, 'слово': 2, 'у': 1}

Нормализация данных:

raw = {"  Python  ": 3.11, " JavaScript": 1.0, "Go  ": 1.21}
clean = {key.strip(): value for key, value in raw.items()}
print(clean)   # {'Python': 3.11, 'JavaScript': 1.0, 'Go': 1.21}

Группировка по первой букве:

words = ["apple", "ant", "banana", "bee", "cherry", "cat"]
by_letter = {
    letter: [w for w in words if w[0] == letter]
    for letter in {w[0] for w in words}   # set comprehension для уникальных букв
}
print(by_letter)
# {'a': ['apple', 'ant'], 'b': ['banana', 'bee'], 'c': ['cherry', 'cat']}

Читаемость — прежде всего

Comprehensions повышают лаконичность, но не должны жертвовать читаемостью:

# Хорошо — понятно с первого взгляда:
squares = {x: x**2 for x in range(1, 6)}

# Плохо — слишком сложно:
result = {k: [v * 2 for v in vals if v > 0] for k, vals in data.items() if k != "skip"}

Если comprehension занимает больше одной строки и требует объяснения — замените обычным циклом.

Проверь себя

Что выведет следующий код?

nums = [1, 2, 3, 4, 5]
d = {x: x ** 2 for x in nums if x % 2 == 0}
print(d)

Чётные числа из [1, 2, 3, 4, 5]: 2, 4. Их квадраты: 4, 16. Результат: {2: 4, 4: 16}.

Итог

  • Dict comprehension: {k: v for ... in ...} — создаёт словарь по формуле.
  • Set comprehension: {expr for ... in ...} — создаёт множество уникальных значений.
  • Оба поддерживают фильтрацию через if.
  • Применяйте для трансформации и фильтрации коллекций в одну строку.
  • При сложной логике — обычный цикл читается лучше.

Модуль 6 завершён! Вы освоили словари, перебор, множества и comprehensions. В следующем модуле глубже погрузимся в работу со строками.

Попробуйте интерактивную версию

Практические задачи, квизы и AI-наставник — бесплатный старт без карты

Перейти к практике