Генераторы Python (Comprehensions)

Генераторы списков (List Comprehensions) — это особый синтаксис, который позволяет создавать списки из других списков и невероятно полезен при работе с числами и одним или двумя уровнями вложенных циклов for.

Из руководства Python 3 tutorial

Генераторы списков предоставляют краткий способ создания списков. [...] или для создания подпоследовательности тех элементов, которые удовлетворяют определенному условию.

Прочтите Python Comprehensions: A step by step Introduction для более подробного введения.

Генератор списка (List comprehension)

Вот как мы создаем новый список из существующей коллекции с помощью цикла For Loop:

# Традиционный подход: создание списка с помощью цикла for
names = ['Charles', 'Susan', 'Patrick', 'George']

new_list = []
for n in names:
    new_list.append(n)

new_list
['Charles', 'Susan', 'Patrick', 'George']

А вот как мы делаем то же самое с помощью генератора списка (List Comprehension):

# Генератор списка: краткий способ создания нового списка
# Синтаксис: [expression for item in iterable]
names = ['Charles', 'Susan', 'Patrick', 'George']

new_list = [n for n in names]  # Создать список со всеми именами
new_list
['Charles', 'Susan', 'Patrick', 'George']
Викторина

Войдите в систему, чтобы ответить на эту викторину и отслеживать свой прогресс обучения

What is the basic syntax of a list comprehension?
A. [expression for item in iterable]
B. (expression for item in iterable)
C. {expression for item in iterable}
D. expression for item in iterable

Мы можем сделать то же самое с числами:

# Вложенный генератор списка: создание кортежей из двух диапазонов
# Эквивалентно вложенным циклам for
n = [(a, b) for a in range(1, 3) for b in range(1, 3)]
n
[(1, 1), (1, 2), (2, 1), (2, 2)]

Добавление условий

Если мы хотим, чтобы new_list содержал только имена, начинающиеся с ‘C’, с помощью цикла for мы бы сделали это так:

# Традиционный подход: фильтрация с условием if
names = ['Charles', 'Susan', 'Patrick', 'George', 'Carol']

new_list = []
for n in names:
    if n.startswith('C'):  # Фильтрация имен, начинающихся с 'C'
        new_list.append(n)

print(new_list)
['Charles', 'Carol']

В генераторе списка мы добавляем оператор if в конец:

# Генератор списка с условием: фильтрация элементов
# Синтаксис: [expression for item in iterable if condition]
new_list = [n for n in names if n.startswith('C')]
print(new_list)
['Charles', 'Carol']
Викторина

Войдите в систему, чтобы ответить на эту викторину и отслеживать свой прогресс обучения

Where does the if condition go in a list comprehension?
A. Before the for keyword
B. After the for clause
C. Inside the expression
D. Before the square brackets

Чтобы использовать оператор if-else в генераторе списка:

# Генератор списка с if-else: условное выражение
# Синтаксис: [expression_if_true if condition else expression_if_false for item in iterable]
nums = [1, 2, 3, 4, 5, 6]
new_list = [num*2 if num % 2 == 0 else num for num in nums]  # Удвоить четные числа
print(new_list)
[1, 4, 3, 8, 5, 12]

Генераторы множеств и словарей (Set and Dict comprehensions)

Основы генераторов списков также применимы к множествам (sets) и словарям (dictionaries).

Генератор множества (Set comprehension)

# Генератор множества: создание множества с использованием синтаксиса генератора
# Синтаксис: {expression for item in iterable}
b = {"abc", "def"}
{s.upper() for s in b}  # Преобразовать все строки в верхний регистр
{"ABC", "DEF"}

Генератор словаря (Dict comprehension)

# Генератор словаря: поменять местами ключи и значения
# Синтаксис: {key_expression: value_expression for item in iterable}
c = {'name': 'Pooka', 'age': 5}
{v: k for k, v in c.items()}  # Поменять местами пары ключ-значение
{'Pooka': 'name', 5: 'age'}
Викторина

Войдите в систему, чтобы ответить на эту викторину и отслеживать свой прогресс обучения

What syntax is used for dictionary comprehensions?
A. [key: value for item in iterable]
B. (key: value for item in iterable)
C. {key_expression: value_expression for item in iterable}
D. {key, value for item in iterable}

Генератор списка может быть создан из словаря:

# Генератор списка из словаря: создание отформатированных строк
c = {'name': 'Pooka', 'age': 5}
["{}:{}".format(k.upper(), v) for k, v in c.items()]  # Формат как "KEY:value"
['NAME:Pooka', 'AGE:5']

Связанные ссылки