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. В следующем модуле глубже погрузимся в работу со строками.