Генератор списков — специальная конструкция, с помощью которой можно по определенным правилам создавать заполненные списки, а также редактировать их.
Главное достоинство генераторов в их короткой записи, обычно это одна строка в квадратных скобках.
Синтаксис генератора списков
[выражение for переменная in источник if условие]
выражение
— результат этого выражения и будет элемент будущего списка
переменная
— переменная для итерации источника
источник
— итерируемый объект
условие
— выражение, использующее переменную для сравнения на каждой итерации
Условие
— не обязательная часть конструкции и может быть пропущена (это будет означать if True
).
Если условие получает результат False
, то выражение пропускается, и элемент этой итерации в список не добавляется.
Примеры генератора списков
a = [i for i in range(1, 5)] print(a) #[1, 2, 3, 4]
Мы создали список из диапазона от 1 до 5 не включительно.
Если это делать без помощи генератора, то это могло бы выглядеть так:
a = [] for i in range(1, 5): a.append(i) print(a) #[1, 2, 3, 4]
Создание списка с помощью генератора выглядит короче и лаконичнее.
Генератор списков с условием
a = [i for i in range(1, 5) if i % 2 == 0] print(a) #[2, 4]
Здесь мы создали список из того же диапазона, но в список добавили только четные числа, использовав условие «если остаток от деления на 2 равен 0».
Создадим список на основе другого списка, поместим во второй список квадраты значений первого списка:
a = [1, 2, 3, 4] b = [i ** 2 for i in a] print(b) #[1, 4, 9, 16]
Здесь мы берем каждый элемент первого списка с помощью цикла for
, возводим во вторую степень и записываем полученное значение в новый список b
.
Работа генератора списков со словарем
a = {1:10, 2:20, 3:30} b = [i * a[i] for i in a] print(b) #[10, 40, 90]
Итоговый список получился из произведений ключа словаря на его значение.
Работа генератора со строкой
a = 'python' b = [i for i in a] print(b) #['p', 'y', 't', 'h', 'o', 'n']
Таким образом, мы получили из строки список, состоящий из букв строки.
Генерация вложенных списков
Если один генератор вложить в другой, то в итоге можно получить вложенные списки:
n = 3 a = [[0 for i in range(n)] for i in range(n)] print(a) #[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
С помощью переменной n
мы задали, сколько вложенных списков и значений во вложенных списках нужно получить.
Далее переменной a
мы присваиваем список созданный генератором в квадратных скобках.
Первая часть [0 for i in range(n)]
— генерирует значения вложенных списков, в данном случае три нуля в каждом списке
Вторая часть for i in range(n)
— генерирует количество этих списков, в данном случае три вложенных списка.
Если все значения вложенных списков должны быть одинаковыми, то можно записать еще проще:
n = 3 a = [[0] * n for i in range(n)] print(a) #[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
Еще один пример:
a = [[i, i+1, i+2] for i in range(3)] print(a) #[[0, 1, 2], [1, 2, 3], [2, 3, 4]]
Дополнительный способ создания вложенных списков с помощью генератора, когда циклы идут друг за другом:
a = [[a, b] for a in range(3) for b in range(3)] print(a) #[[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
Для наглядности этот генератор можно записать так:
a = [[a, b] for a in range(3) for b in range(3) ] print(a) #[[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
Здесь имеются вложенные циклы for
, которые идут один за другим. Второй цикл for b
вложен в первый цикл for a
.
Т.е. в одной итерации цикла for a
мы получаем 3 итерации цикла for b
.
Таким образом, формируется список из 9 вложенных списков.
Решение распространенных задач с помощью генераторов списков
Вводим числа через пробел, на выходе получаем список с элементами int():
a = input().split() a = [int(i) for i in a] print(a) #1 2 3 4 5 #[1, 2, 3, 4, 5]
Разбить целое число на цифры и получить их в виде списка:
num = 95874 x = [int(a) for a in str(num)] print(x) #[9, 5, 8, 7, 4]
Сумма пар значений двух списков:
lst_in1 = [1, 2, 3, 4, 5] lst_in2 = [1, 2, 3, 4, 5] lst = [lst_in1[i] + lst_in2[i] for i in range(len(lst_in1))] print(lst) #[2, 4, 6, 8, 10]
Преобразовать двумерный список в одномерный:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] new_list = [x for row in matrix for x in row ] print(new_list) #[1, 2, 3, 4, 5, 6, 7, 8, 9]
Транспонирование матрицы:
1 2 3 4 1 5 9 5 6 7 8 2 6 10 9 10 11 12 3 7 11 4 8 12
a = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] a = [[row[i] for row in a] for i in range(len(a[0]))] print(a) #[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
Cгенерировать вложенный список размером N x N
Где первая строка содержала бы все нули, вторая — все единицы, третья — все двойки и так до N-й строки.
n = int(input()) for i in range(n): lst = [i for x in range(n)] print(*lst) #4 #0 0 0 0 #1 1 1 1 #2 2 2 2 #3 3 3 3