Фрагмент лекции

Comprehensions в Python: распаковка * и ** внутри (PEP 798)

Генераторы списков, словарей, множеств и генераторные выражения. Для опытных: новая распаковка внутри comprehension в 3.15 вместо двойного for и цепочек слияния словарей.

list comprehension генераторное выражение распаковка PEP 798
Что вы изучите в этой лекции
  • Заменять циклы comprehension там, где это читаемо
  • Экономить память генераторами
  • Склеивать вложенные списки и словари новой распаковкой

Начало лекции

Двойной for, который все пишут задом наперёд

  • Склейка вложенных списков: [x for g in groups for x in g]
  • Порядок for — как во вложенных циклах, сверху вниз
  • В 3.15: [*g for g in groups]

Спросите опытного разработчика, как одной строкой склеить список списков. Он напишет квадратные скобки с двумя for внутри — и почти наверняка сначала перепутает их порядок. Эта запись настолько неочевидна, что её годами копируют со Stack Overflow, не пытаясь понять. В Python 3.15 появился способ проще: звёздочка прямо внутри генератора списка. Сегодня разберём, как устроены такие выражения с нуля, а в конце — эту новинку.

weeks = [[250, 120], [300], [99, 450]]

# было: двойной for, порядок легко перепутать
flat = [a for week in weeks for a in week]

# стало в Python 3.15 (PEP 798)
flat = [*week for week in weeks]
print(flat)

Из пяти строк в одну: list comprehension

  • Схема: [выражение for x in коллекция]
  • Результат — новый список, исходный не меняется
  • Читается слева направо: «что» → «откуда»

Начнём с самого частого случая. Есть список сумм, нужно получить список тех же сумм с наценкой двадцать процентов. Классический путь: завести пустой список, пройти циклом, добавить каждый результат. Четыре строки ради простой мысли. Comprehension записывает ту же мысль одной строкой: в квадратных скобках сначала говорим, что хотим получить, а потом — откуда берём. Читается почти как фраза: «сумма на один и два для каждой суммы из списка».

amounts = [250, 1200, 99, 450]

# классический цикл
with_vat = []
for a in amounts:
    with_vat.append(a * 1.2)

# то же самое — comprehension
with_vat = [a * 1.2 for a in amounts]
print(with_vat)

Фильтр в конце, выбор в начале

  • Фильтр: [a for a in xs if a > 200] — if в конце
  • Выбор значения: [x if усл else y for a in xs] — в начале
  • Можно и то и другое сразу

Comprehension умеет отбирать элементы. Дописали в конце if с условием — и в результат попадут только подходящие суммы, например больше двухсот. А если нужно не выбросить элемент, а превратить его в одно из двух значений, условие ставится в начало, в виде «это, если так, иначе то». Новички путают эти два места постоянно. Запомните просто: условие в конце — фильтр, условие в начале — выбор, что положить.

amounts = [250, 1200, 99, 450]

big = [a for a in amounts if a > 200]          # фильтр
labels = ["крупная" if a > 1000 else "обычная" # выбор
          for a in amounts]
print(big)
print(labels)

Полная лекция — по подписке

Ещё 10 слайдов в полной версии.

Видео, все слайды, конспект, тесты, AI-тьютор и собеседование открываются после входа и оформления подписки.

Войти или зарегистрироваться Оформить подписку

Содержание лекции

  1. Двойной for, который все пишут задом наперёд
  2. Из пяти строк в одну: list comprehension
  3. Фильтр в конце, выбор в начале
  4. Словари и множества тем же способом
  5. Генераторное выражение: не хранить, а выдавать
  6. Генератор внутри sum, any, max
  7. Грабли: comprehension на три этажа
  8. ❓ Стоп-проверка: чему равен x после comprehension?
  9. 💡 Разбор: у comprehension своя область видимости
  10. Что нового: * и ** внутри comprehension (3.15, PEP 798)
  11. Слияние словарей: {**layer for layer in layers}
  12. Грабли новой распаковки: тернарник без скобок
  13. Итог: подсчёт трат в три строки

Статьи по теме лекции

Все лекции курса

  1. Python 3.15 с нуля и для опытных: что нового и как учить
  2. Python 3.15: установка, REPL и первый скрипт за десять минут
  3. Переменные, числа и строки в Python: f-строки и t-строки
  4. Условия, циклы и match/case в Python: управляем ходом программы
  5. Списки, кортежи, словари и множества: frozendict в Python 3.15
  6. Comprehensions в Python: распаковка * и ** внутри (PEP 798)
  7. Функции и аннотации типов в Python: от def до sentinel
  8. Ошибки и исключения в Python 3.15: читаем трейсбек и подсказки «Did you mean»
  9. Модули, пакеты и ленивые импорты в Python 3.15 (PEP 810)
  10. Файлы, JSON и CSV в Python: pathlib и UTF-8 по умолчанию
  11. Классы и dataclasses в Python: ООП без лишнего кода
  12. Асинхронность и потоки в Python: asyncio, TaskGroup и free-threading
  13. Профилирование Python 3.15: Tachyon вместо cProfile и итоговый проект