Списковые включения (List comprehension)

borntohack

змееуст
Команда форума
Модератор
Апр 22, 2020
78
62
18
39
Москва, РФ
СПИСКОВЫЕ ВКЛЮЧЕНИЯ (LIST COMPREHENSION)

Довольно часто мы сталкиваемся с задачей создания списка путем итерирования по чему-либо, будь то строка, или другой список. В частном случае маппинга (описан выше) - мы формируем новый список путем итерирования по оригинальному списку.

Примитивный код такого формирования порой выглядит, хотя и понятно, но неразумно длинно (допустим, для квадратов чисел):
Python:
somelist = [1,2,3,4,5,6,7,8,9]
newlist = []
for i in somelist:
    newlist.append(i**2)
Этот же код можно удобно записать в виде спискового включения (нам не нравится такое название, поэтому здесь и далее я буду называть их "компрехами"):
Python:
somelist = [1,2,3,4,5,6,7,8,9]
newlist = [i**2 for i in somelist]

Можно заметить, что в наших примитивных кодах всё же все не так примитивно. Обычно мы вполняем одновременно и маппинг и фильтрацию внутри цикла for прежде, чем добавить элемент (например, новый список должен содержать квадраты только четных чисел). В этом случае мы пишем что-то вроде:
Python:
somelist = [1,2,3,4,5,6,7,8,9]
newlist = []
for i in somelist:
    if not i%2:
        newlist.append(i**2)
Но, "компрехи" позволяют делать и это довольно лаконично:
Python:
somelist = [1,2,3,4,5,6,7,8,9]
newlist = [i for i in somelist if not i%2]

В общем случае, "компрех" описывается таким правилом (справедливо и для генераторов, но о них в других статьях):
Код:
[новый_элемент for новый_элемент in итерируемое if условие, в котором доступно значение элемента]
Так же в "компрехах" доступны и вложенные циклы. Они записываются слева направо.
Например, для раскрытия двумерного массива (матрицы) в одномерный мы обычно пишем что-то вроде:
Python:
matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
planar = []
for i in matrix:
    for j in i:
        planar.append(j)
на выходе будет одномерный ("планарный") массив [1,2,3,4,5,6,7,8,9,10,11,12]

Тот же код на "компрехах":
Python:
matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
planar = [j for i in matrix for j in i]

Стоит заметить, что условие все равно записывается в конце после всех вложенных циклов for. В условии доступны все итераторы, с которыми в данный момент работают циклы.
 

Форум IT Специалистов