Объяснение к уроку
После этого урока ты сможешь:
sum(), any() или all() без создания промежуточного списка.Списковое включение создает список результатов сразу:
adjusted = [score + 5 for score in scores]Генераторное выражение использует круглые скобки вместо квадратных. Оно описывает значения, которые будут создаваться по мере запроса итератором, а не формирует итоговый список сразу:
adjusted = (score + 5 for score in scores)Используй его, когда операция может обрабатывать значения по одному — например sum(), any() или all(). Ты можешь передать выражение напрямую в функцию. Для единственного аргумента внешние скобки генератора часто можно опустить: sum(x * 2 for x in values).
В отличие от списка, генератор является однопроходным. После того как ты его исчерпал, повторный перебор того же генератора не дает значений. Если тебе нужны значения несколько раз, используй списковое включение, материализуй генератор с помощью list() или создавай новый генератор для каждого прохода.
Функции any() и all() могут останавливаться раньше: any() останавливается на первом истинном элементе, а all() — на первом ложном. Правила для пустых входных данных остаются такими же, как в предыдущем уроке (any — ложно; all — истинно). Генераторные выражения особенно естественны для однопроходных проверок.
base_prices = [12, 20, 8]
total = sum(price * 2 for price in base_prices)
print(f"Total: {total}")Вывод:
Total: 80Умножение вычисляется по мере того, как sum() запрашивает каждый элемент; отдельный список удвоенных цен не требуется.
readings = [18, -1, 24, 0]
valid_total = sum(value for value in readings if value >= 0)
print(valid_total)Вывод:
42Условие if исключает недопустимые отрицательные показания из расчета, сохраняя при этом допустимый ноль.
labels = ["ready", "paused", "ready"]
has_pause = any(label == "paused" for label in labels)
print(f"Paused: {has_pause}")Вывод:
Paused: TrueФункция any() может завершиться, как только генератор предоставит одно совпадение.
values = (part.upper() for part in ["a", "b"])
print(list(values))
print(list(values))Вывод:
['A', 'B']
[]Второй проход пуст, потому что values был исчерпан. Используй список, если оба прохода должны содержать результаты.
| Потребность | Предпочтительный подход |
|---|---|
| Сохранить результаты для повторного использования | [expression for item in items] |
| Обработать результаты один раз | (expression for item in items) |
| Агрегировать значения | sum(expression for item in items) |
| Проверить хотя бы одно совпадение | any(predicate for item in items) |
| Проверить каждое значение | all(predicate for item in items) |
| Использовать результаты позже | Материализовать с list(...) или создать генератор заново |
all() на пустом генераторе доказательством того, что партия содержала проверки.sum(), any() или all(), когда генератор понятнее.