Розглянемо одну конструкцію мови, яка допоможе скоротити кількість рядків коду. Не рідко рівень програміста на Python можна визначити за допомогою цієї конструкції. Приклад коду:a =[]for x in range(5, 10): if x % 2 == 0: x *= 2 else: x += 1 a.append(x)print(a)А зараз спробуємо ці 8 рядків перетворити в два:[6, 12, 8, 16, 10]a = [x * 2 if x % 2 == 0 else x + 1 for x in range(5, 10)]print(a)[6, 12, 8, 16, 10]
Генератори списків - це простий і лаконічний спосіб створення списків з інших ітеріруемих об'єктів. Найпростіший генератор складається з виразу і циклу, які потрібно помістити в квадратні дужки:a = [x**2 for x in range(10)]print(a)[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]Так само вираз може містити будь-яку кількість змінних, але в цьому випадку для кожної змінної оголошується окремий цикл і вказується власний ітеріруемий об'єкт:a = [x + y for x in range(1, 4) for y in range(5, 10)]print(a)[6, 7, 8, 9, 10, 7, 8, 9, 10, 11, 8, 9, 10, 11, 12]
Кількість ітерацій внутрішніх циклів може залежати від зовнішніх циклів, наприклад:a = [str(x) + str(y) for x in range(3) for y in range(x+3)]['00','01','02','10','11','12','13','20','21','22','23','24']Що аналогічно наступному коду:a = []for x in range(3): for y in range(x + 3): a.append(str(x) + str(y))print(a)['00','01','02','10','11','12','13','20','21','22','23','24']
Більш наочно роботу генератора можна розглянути на прикладі генерації списку випадкових чисел. Для цього перш за все імпортуємо модуль random:import random # імпорт модуляr = [random.randint(-20, 20) for x in range(20)] # виклик методу randint (-20, 20) для генерації випадкових чисел в зазначеному деапазонеprint(r) # вивід:[12, 10, 14, 19, -14, 19, 17, 2, -17, -10, 0, 2, -16, -12, 5, -3, -8, 7, 18, -3]
Вкладені генератори, можуть бути використані для створення різних матриць:# створюємо квадратну матрицюn = 4a = [[i for i in range(j,j+n)] for j in range(0,n**2-1, n)]print(a)[[0,1,2,3], [4,5,6,7], [8,9,10,11], [12,13,14,15]]# створюємо прямокутну матрицюl, k = 3, 6a = [[i for i in range(j, j + k)] for j in range(0, l*k-1, k)]print(a)[[0,1,2,3,4,5], [6,7,8,9,10,11], [12,13,14,15,16,17]]
Перейдемо до коду: y = [8 for x in range(1,10)] # 8 -це найпростіше вираження, range (1,10) - колекція, генерує значення від 1 до 9 включноprint(y) # вивід: [8, 8, 8, 8, 8, 8, 8, 8, 8]Якщо замість виразу 8 підставити значення x, наш список заповниться цифрами від 1 до 9:y = [x for x in range(1,10)] # x прийме значення від 1 до 10print(y) # вивід:[1, 2, 3, 4, 5, 6, 7, 8, 9]Те ж справедливо і для x в квадраті:y = [x**2 for x in range(1,10)]print(y) # вивід:[1, 4, 9, 16, 25, 36, 49, 64, 81]
Вправа: генератори списків. На вході програма отримує список цілих чисел s. Ваше завдання - вивести наступні списки по одному в рядку: Список, що складається з квадратів s. Список, що складається із залишків поділу на 11 елементів s. Список, що складається тільки з парних елементів s. Список, що складається тільки з елементів s з непарним кількістю цифр. Список, що складається тільки з двозначних елементів s, записаних 2 рази поспіль. Список, що складається з елементів s, що стоять на позиціях, що не кратних 3. Вхідні дані: У єдиному рядку записані числа, розділені пробілами. s = [8, 5, 15, 101, 42, 1]Вихідні дані: У кожній з шести рядків виведіть відповідний список у стандартному форматі python'а.[64, 25, 225, 10201, 1764, 1][8, 5, 4, 2, 9, 1][8, 42][8, 5, 101, 1][1515, 4242][5, 15, 42, 1]