Что такое comprehensions (включения) в Python?

Ответ

Comprehensions (включения, или генераторы коллекций) — это синтаксический сахар в Python для создания коллекций (списков, словарей, множеств) из итерируемых объектов в одну строку. Они делают код более кратким и читаемым по сравнению с традиционными циклами for.

Общая структура: новая_коллекция = [выражение for элемент in итерируемый_объект if условие]

Основные виды:

  1. List Comprehension (Списковое включение) Создаёт новый список. Это наиболее распространённый вид.

    # Создать список квадратов чётных чисел от 0 до 9
    squares = [x**2 for x in range(10) if x % 2 == 0]
    # Результат: [0, 4, 16, 36, 64]
  2. Dictionary Comprehension (Словарное включение) Создаёт новый словарь.

    # Создать словарь, где ключ - число, а значение - его квадрат
    square_map = {x: x**2 for x in range(5)}
    # Результат: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
  3. Set Comprehension (Множественное включение) Создаёт новое множество, автоматически удаляя дубликаты.

    # Создать множество уникальных гласных из строки
    vowels = {char for char in 'hello world' if char in 'aeiou'}
    # Результат: {'o', 'e'}
  4. Generator Expression (Выражение-генератор) Синтаксически похоже на списковое включение, но использует круглые скобки. Создаёт объект-генератор, который вычисляет значения «на лету» (лениво), а не хранит их все в памяти.

    # Создать генератор для удвоенных значений
    doubles_gen = (x * 2 for x in [1, 2, 3])
    
    # Генератор не хранит значения, их нужно итерировать
    for value in doubles_gen:
        print(value) # Выведет 2, 4, 6

Преимущества:

  • Краткость и читаемость: Код становится более декларативным.
  • Производительность: Часто работают быстрее, чем эквивалентные циклы for с append().
  • Изоляция области видимости: В Python 3 переменная цикла (x в примерах) не «протекает» в глобальную область видимости.

Ответ 18+ 🔞

Слушай, а вот эти ваши comprehension'ы в Python — это ж просто песня, а не фича! Ну реально, как будто кто-то взял обычный цикл, выжал из него всю воду и оставил голую суть. Красота, блядь!

Вот смотри, обычно ты пишешь как? Цикл, создаёшь пустой список, потом в него что-то пихаешь... Пиздец, целых три строки! А можно в одну, ёпта!

Основная идея — как бутерброд собираешь: [что положить for штука in коробка_со_штуками if штука_нормальная]

И вот какие бывают бутерброды:

  1. Для списков (List Comprehension) Самый популярный, его все любят. Всё, что в квадратных скобках — превращается в список.

    # Раньше бы писали цикл, а теперь — раз, и готово!
    квадраты_чётных = [x**2 for x in range(10) if x % 2 == 0]
    # Получится: [0, 4, 16, 36, 64]

    Читай так: «Дайте мне квадрат икса для каждого икса от нуля до девяти, но только если икс чётный, блядь!»

  2. Для словарей (Dictionary Comprehension) Тут уже фигурные скобки и нужно указать пару «ключ: значение».

    # Сделаем справочник «число -> его квадрат»
    справочник_квадратов = {x: x**2 for x in range(5)}
    # Выдаст: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

    Проще простого, ёпта! Как будто табличку умножения на коленке составил.

  3. Для множеств (Set Comprehension) Тоже фигурные скобки, но без двоеточий. Автоматом выкинет все повторы — вот что главное!

    # Выудим все гласные из фразы, дубликаты сами исчезнут
    гласные = {char for char in 'hello world' if char in 'aeiou'}
    # На выходе: {'o', 'e'}  (порядка, ясное дело, никакого)
  4. Выражения-генераторы (Generator Expression) А вот это, сука, хитрая жопа! Выглядит как списковое включение, но в круглых скобках. И работает оно лениво — ничего не хранит в памяти, пока не попросишь.

    # Создаём не список, а генератор — этакую обещашку выдать значения
    удвоитель = (x * 2 for x in [1, 2, 3])
    
    # А вот теперь просим выдать, по одному
    for val in удвоитель:
        print(val)  # Напечатает 2, потом 4, потом 6

    Это овердохуища удобно, когда данных — пиздец сколько, а память одна.

Чем они офигенны?

  • Короче, чем циклами. Глаза не разбегаются, всё в одну строчку.
  • Часто быстрее. Интерпретатору такую конструкцию проще жрать.
  • Чище. Переменная цикла (та же x) не остаётся висеть в памяти после работы — не засоряет пространство, молодец!

В общем, вещь! Освоил — и код сразу стал выглядеть на уровень круче. Главное — не увлекаться и не делать вложенные comprehension'ы на три этажа, а то потом сам не разберёшь, что написал, блядь.