List comprehension появился ещё в ранних версиях Python. Этот синтаксический сахар был заимствован из функциональных языков. Он делает код компактнее и иногда даже чуть быстрее, чем обычный цикл for.
Многие неопытные разработчики используют list comprehensions без понимания их особенностей, что приводит к ухудшению читаемости или появлению неожиданных эффектов в коде. Также новым разработчикам сложно различить использование list comprehensions и функций map/filter/lambda.
List comprehension — это способ быстро создать новый список, применяя выражение к каждому элементу исходной последовательности:
nums = [1, 2, 3, 4] squares = [x*x for x in nums if x % 2 == 0] # [4, 16]
Ключевые особенности:
Возвращает ли list comprehension генератор?
Нет, возвращается именно список. Генератор создаётся с помощью круглых скобок:
# Это генератор: (x*x for x in range(10)) # Это список: [x*x for x in range(10)]
Можно ли внутри list comprehension присваивать значения переменным?
В стандартном синтаксисе нельзя. Только с помощью выражения "walrus" (:=) с Python 3.8+:
[x for x in (y := range(5))] # Ошибка! [x for x in [(y := i*i) for i in range(5)]] # y виден только в этом списке
Можно ли изменять внешние переменные внутри list comprehension?
Переменная, объявленная внутри list comprehension — локальная, не будет видна снаружи. Это часто путает новичков при вложенных конструкциях.
** Негативный кейс Разработчик использует вложенные list comprehensions для сложной трансформации данных за одну строчку. Плюсы: Код компактный, эффект "я знаю Python!" Минусы: Тяжело читать, страдают новые коллеги, отладка становится мучением ** Позитивный кейс Разработчик использует простые list comprehensions для фильтрации и преобразования коротких списков, а для сложных операций пишет явные функции и циклы. Плюсы: Код легко читать, поддерживать и расширять Минусы: В некоторых случаях код чуть длиннее и используются дополнительные переменные