Найти в Дзене
Bednyakov

Создание двумерного списка с помощью list comprehensions в Python

Столкнулся с интересной и совершенно неочевидной для меня задачкой, которую решил почти методом научного тыка. Условия: Заказчик требует сгенерировать двумерный список из четырех списков использую только list comprehensions. На выходе должно получиться ни больше ни меньше, а вот это: [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] Очевидно, что генерировать четыре списка и потом сложить их в один- не лучшая идея. По всей видимости решение должно укладываться в одну строчку, нужно просто найти все переменные, с которыми можно поработать в цикле. Однако первое однострочное решение, которое пришло на ум, выглядит страшновато:
big_list = [[x for x in range(1, 13, 4)], [x for x in range(2, 13, 4)], [x for x in range(3, 13, 4)], [x for x in range(4, 13, 4)]] По сути я всё так же генерирую четыре списка по отдельности, просто уложив их большой список. Кроме того, строка получилась чрезвычайно громоздкая, повторяющая одни и те же действия. А это означает, что все четыре повторения можно сложи

Столкнулся с интересной и совершенно неочевидной для меня задачкой, которую решил почти методом научного тыка.

Условия:

Заказчик требует сгенерировать двумерный список из четырех списков использую только list comprehensions.

На выходе должно получиться ни больше ни меньше, а вот это:

[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

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

Однако первое однострочное решение, которое пришло на ум, выглядит страшновато:


big_list = [[x for x in range(1, 13, 4)], [x for x in range(2, 13, 4)], [x for x in range(3, 13, 4)], [x for x in range(4, 13, 4)]]

По сути я всё так же генерирую четыре списка по отдельности, просто уложив их большой список. Кроме того, строка получилась чрезвычайно громоздкая, повторяющая одни и те же действия. А это означает, что все четыре повторения можно сложить в какое-то одно действие.

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

В итоге конечное решение получилось таковым:

new_list = [[x for x in range(i, 13, 4)] for i in range(1,5)]

Добавив внешний цикл for получилось убить двух зайцев: сгенерировать четыре списка и привязать "старт" во внутренней range() каждого генерируемого списка к переменной- счетчику.

На мой непрофессиональный взгляд вышло достаточно красиво, хотя в питонизме я абсолютный новичок, да и про list comprehensions узнал буквально вчера. Поэтому буду очень рад, если подкинете и другие решения этой задачки.

А бонусом покажу распаковку двумерного списка с помощью list comprehensions. Дан список:

nice_list = [[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
[[10, 11, 12], [13, 14, 15], [16, 17, 18]]]

Решение:


new_list = [x for lst in nice_list for elem in lst for x in elem]

Вывод: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

Благодарю за внимание.