Все разделы
Выбрать школу

Школа. Увлечения. Большое будущее.

PROSCHOOLS · ОБРАЗОВАНИЕ РЯДОМ

Ваш город

Выберите город, чтобы находить образование и возможности рядом.

Как учитываем городКаталог и кнопки «Выбрать школу» покажут школы выбранного города.Онлайн-курсы, учебник, ГДЗ и задания к экзаменам доступны по всей России.

Популярные города

Будет выбран: Вся Россия

Учебные материалы останутся прежними.

Поиск по сайту

По всему сайтуШколы выбранного города — выше в результатах

С чего начнём?

↑ ↓ — выбрать результат · Enter — открыть · Esc — закрыть

Генераторы списков: создаём списки одной строкой

💻 Информатика · 9 класс

Генератор списка — компактная запись цикла, который строит новый список: квадраты чётных чисел, имена лучших учеников, проценты баллов. Учимся читать и писать [x ** 2 for x in numbers if x % 2 == 0].

Клавиатура в компьютерном классе
Иллюстрация к предмету «Информатика»Hmartil · Wikimedia Commons · CC BY-SA 4.0

Зачем нужен генератор

Часто новый список строится по правилу «возьми каждый элемент старого, что-то с ним сделай, отбрось лишнее». Цикл с append справляется, но занимает четыре строки. Генератор списка записывает то же правило в одну строку, что удобно для простого преобразования и фильтрации.

squares = []
for x in range(10):
    squares.append(x ** 2)

# то же самое одной строкой:
squares = [x ** 2 for x in range(10)]

Пример 1. Квадраты чётных чисел

def squares_of_even(limit):
    return [x ** 2 for x in range(limit + 1) if x % 2 == 0]

print(squares_of_even(10))
# [0, 4, 16, 36, 64, 100]

Структуру читают так: [выражение for элемент in последовательность if условие]. Фильтр if x % 2 == 0 оставляет только чётные числа, выражение x ** 2 превращает их в квадраты. Порядок частей важен: сначала for, потом if. Такое списковое включение можно переписать циклом с append. Произвольный цикл с побочными действиями не обязательно имеет полезную эквивалентную короткую запись.

Пример 2. Успеваемость класса

def passing_students(grades):
    good = [name for name, marks in grades.items()
            if marks and sum(marks) / len(marks) >= 4]
    return sorted(good)

grades = {'Аня': [5, 5], 'Борис': [3, 3], 'Вера': [4, 5], 'Гриша': []}
print(passing_students(grades))  # ['Аня', 'Вера']

Здесь перебираются пары словаря методом items(), условие отсекает пустые списки (if marks) и средний балл ниже 4. Функция sorted нужна, потому что словарь хранит имена в порядке вставки, а не по алфавиту. Переменная обхода внутри спискового включения имеет отдельную область. Если снаружи уже было x, его значение сохраняется. В первом примере x после обычного цикла равно 9, и последующее включение не удаляет это имя.

Пример 3. Два цикла и проценты

def normalize_scores(scores, maximum):
    if maximum <= 0:
        raise ValueError('maximum должен быть положительным')
    return [round(score / maximum * 100, 1) for score in scores]

def multiplication_table():
    return [f'{a} * {b} = {a * b}' for a in range(1, 10) for b in range(1, 10)]

В генераторе можно писать несколько for подряд — циклы вложены: сначала перебирается a, для каждого a — b. Функция normalize_scores показывает, что «выражение» может быть любым, в том числе вызовом round с округлением.

В normalize_scores передаются числовые баллы и положительный максимум шкалы. Для maximum равного нулю или отрицательному функция отклоняет вход, а не делит на неверный максимум. Списковое включение сразу строит список в памяти. Генераторное выражение в круглых скобках выдаёт элементы постепенно и является другим объектом.

Когда генератор не нужен

Если при построении списка делается несколько разных действий (печать, запись в файл, ветвления с continue), обычный цикл читабельнее. Генератор хорош именно для «преобразуй и отфильтруй».

Проверь себя

  1. Что вернёт [x for x in range(6) if x % 2 == 1]? Ответ: [1, 3, 5] — остаток 1 дают нечётные числа.
  2. Запишите генератор: длины слов в списке words. Ответ: [len(w) for w in words].
  3. Что выведет print([a + b for a in 'xy' for b in '12'])? Ответ: ['x1', 'x2', 'y1', 'y2'] — вложенные циклы идут по порядку: для каждого a все b.
  4. Как получить список квадратов только положительных чисел из data = [-2, 3, 0, 5]? Ответ: [x ** 2 for x in data if x > 0] даст [9, 25].

Кратко о главном

Генератор списка — [выражение for элемент in итерируемое if условие]. Он короче цикла с append и не оставляет переменную цикла. Несколько for внутри работают как вложенные циклы. Для сложных побочных действий выбирайте обычный цикл.

Связанные материалы

Источники и материалы