Абстракция списков

Абстракции - это та особенность Python, которой мне будет очень сильно недоставать, если я сменю язык программирования. Абстракции - это конструкторы, позволяющие создавать последовательности из других последовательностей. В Python (2 и 3) есть три типа подобных абстракций:
  • абстракции списков
  • абстракции словарей
  • абстракции множеств
  • абстракции генераторов
Мы обсудим все три, хотя освоив абстракции списков вы легко перенесёте знания на остальные типы.

list абстракции

Абстракции списков открывают доступ к простому и лаконичному синтаксису генерации списков. Конструкция состоит из квадратных скобок содержащих выражение и оператор for, плюс дополнительные for или if при необходимости. Выражения могут быть любыми, т.е. вам разрешается иметь любые элементы внутри списка. Результатом работы будет новый список после исполнения выражения с оглядкой на for и if.
Шаблон использования:
variable = [out_exp for out_exp in input_list if out_exp == 2]
Вот короткий пример:
multiples = [i for i in range(30) if i % 3 == 0]
print(multiples)
# Вывод: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
Такой синтаксис может быть очень удобен для быстрого создания списков. Использование такого подхода вместо функции filter позволяет повысить читаемость кода (без потери скорости исполнения). Особенно хорошо абстракции списков заменяют создание нового простого списка при помощи цикла for и append. Наглядный пример:
squared = []
for x in range(10):
squared.append(x**2)
Вы можете сократить решение до одной строки:
squared = [x**2 for x in range(10)]

dict абстракции

Абстракции словарей используются схожим образом. Вот пример, на который я недавно наткнулся:
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
mcase_frequency = {
k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0)
for k in mcase.keys()
}
# mcase_frequency == {'a': 17, 'z': 3, 'b': 34}
В примере выше мы суммируем значения ключей, которые отличаются только регистром. Лично я редко пользуюсь этим методом. Вы также можете легко поменять местами ключи и значения в словаре:
{v: k for k, v in some_dict.items()}

set абстракции

Абстракции множеств схожи с абстракциями списков. Единственное различие - используются фигурные скобки {}. Вот пример:
squared = {x**2 for x in [1, 1, 2]}
print(squared)
# Вывод: {1, 4}

Абстракции генераторов

Абстракции генераторов похожи на абстракции списков. Единственное отличие - генераторы не выделяют память сразу под все элементы, а возвращают их один за одним, что намного более экономно:
multiples_gen = (i for i in range(30) if i % 3 == 0)
print(multiples_gen)
# Output: <generator object <genexpr> at 0x7fdaa8e407d8>
for x in multiples_gen:
print(x)
# Outputs numbers

Примечание

В русскоязычном сегменте интернета распространение получили другие названия абстракций, в частности используются понятия генераторы списков/словарей/множеств. Данные термины, однако, не совсем корректны, так как не являются генераторами (здесь возможна путаница с genexp, т.е. (x**2 for x in [1, 2, 3]) - генераторное выражение, возвращающее объект генератора). В английском используется list/dict/set comprehension (comprehension - включение). Рекомендуется использовать либо вариант списковые включения, либо английское название или его краткую форму listcomp/dictcomp/setcomp.