Шаг 93.
Однострочники Python. Алгоритмы. Вычисление булеана с помощью функционального программирования. Код и принцип работы

    На этом шаге мы закончим изучение этого вопроса.

Код

    В примере 6.5 приведено однострочное решение для вычисления булеана заданного множества s.


Пример 6.5. Однострочное решение для вычисления булеана заданного множества
## Зависимости
from functools import reduce

## Данные
s = {1, 2, 3}

## Однострочник
ps = lambda s: reduce(lambda P, x: (1)P + [subset | {x} for subset in P],
                      s, (2)[set()])

## Результат
print(ps(s))
Архив с файлом можно взять здесь.

    Угадайте, что вернет этот фрагмент кода!

Принцип работы

    Идея данного однострочника заключается в том, чтобы начать формирование булеана с пустого множества (2) и последовательно добавлять в него подмножества (1), пока их больше не останется.

    Изначально булеан содержит только пустое множество. На каждом шаге мы берем один элемент x из набора данных s и создаем новые подмножества, получающиеся естественным образом путем добавления x в каждое из подмножеств булеана (2). Как вы уже видели чуть раньше, размер булеана удваивается каждый раз, когда берется дополнительный элемент x из набора данных s. Таким образом можно наращивать булеан из n подмножеств по одному элементу набора данных за раз (но по n подмножеств за раз). Обратите внимание, что размер булеана растет экспоненциально: каждый новый элемент набора данных x приводит к удвоению размера булеана. Это неотъемлемое свойство булеанов: они стремительно заполняют любое хранилище - даже в случае относительно небольших наборов данных всего из нескольких десятков элементов.

    С помощью функции reduce() мы производим хранение текущего булеана в переменной P (изначально содержащей только пустое множество). С помощью спискового включения функция reduce() создает новые подмножества - по одному для каждого существующего подмножества - и добавляет их в булеан P. В частности, она добавляет значение x из набора данных в каждое из подмножеств и тем самым удваивает размер булеана (который теперь содержит подмножества с элементом x набора данных и без него). Благодаря этому функция reduce() последовательно "сливает воедино" два элемента: булеан P и элемент x из набора данных.

    Поэтому результат нашего однострочника выглядит следующим образом:

# Результат
print(ps(s))
# [set(), {1}, {2}, {1, 2}, {3}, {1, 3}, {2, 3}, {1, 2, 3}]

    Данный однострочник наглядно демонстрирует важность понимания лямбда-функций, списковых включений и операций над множествами.

    На следующем шаге мы рассмотрим реализацию шифра Цезаря с помощью расширенного доступа по индексу и спискового включения.




Предыдущий шаг Содержание Следующий шаг