Python

Зачем нужен list comprehension в Python?

Чтобы сохранить строчки кода.

List comprehensions — это один из способов создания Pythonic-однострочников (one-liners) с итерируемыми списками.

В качестве примера рассмотрим продуктовую корзину. Вы вытаскиваете каждый товар и кладете на кассу. В таком случае, продуктовую корзину можно назвать iterable.

Разберем этот пример с помощью кода. Мы находимся в вычислительном магазине, поэтому будем покупать только числа.

# Create a list of numbers (our shopping cart)
cart = [3, 4, 12, 17, 19, 21, 23, 26, 30]

# Pass items to the cashier
cashier = []
for item in cart:
cashier.append(item)
print(cashier)

# The output is the same as the cart
Output: [3, 4, 12, 17, 19, 21, 23, 26, 30]

Какие действия были выполнены?

  1. Создаем список элементов в cart
  2. Создаем пустой список cashier (cashier еще не содержит элементов)
  3. Используем цикл for для повторения каждого item в cart
  4. Каждый item добавляем в список cashier с .append()
  5. Затем проверяем, какие элементы находятся в cashier с помощью print()

Как выполнить эти действия с list comprehension?

# Pass items to second cashier but with a list comprehension
cashier_2 = [item for item in cart]
print(cashier_2)

# The output is the same as cashier (and the same as cart)
Output: [3, 4, 12, 17, 19, 21, 23, 26, 30]

Что происходит здесь?

Те же самые действия, написанные другим способом. Сравним.

Сравнение non-list comprehension с list comprehension
  1. Создание cashier выделено синим. Слева он занимает собственную строку, а справа создается одновременно с остальными элементами.
  2. Повторение cart выделено зеленым. item создается при запуске цикла for. Этот шаг аналогичен извлечению одного товара (item) из продуктовой корзины и передачи его кассиру.
  3. Обновление cashier с каждым item выделено красным. Единственное различие с левой стороны заключается в необходимости оператора .append(). Благодаря list comprehension справа оператор  .append() можно не использовать.

Мы выполнили те же самые действия на одной строке кода, вместо трех. В случае, если проект Python занимает 1000 строк, его можно сократить до 300. Однако подобные сокращения можно выполнить не всегда. Это просто пример выполнения аналогичных действий с Pythonic-однострочником.

Что еще можно сделать с помощью list comprehensions в Python?

Рассмотрим еще несколько примеров.

cashier_3 работает только с четными числами. Как это изменить?

С помощью conditional, который выполняет действие при значении True и останавливается при False.

# Make a new cart
cart = [5, 7, 9, 10, 12, 15, 19, 20, 22]

# Only give cashier_3 even numbers
cashier_3 = []
for item in cart:
if item % 2 == 0:
cashier_3.append(item)
print(cashier_3)

# Thanks to the conditional the output is only the even numbers
Output: [10, 12, 20, 22]

Как будет выглядеть код с list comprehension?

cashier_3 = [item for item in cart if item % 2 == 0]
print(cashier_3)

# The output is the same as above
Output: [10, 12, 20, 22]

Что здесь происходит?

Пример non-list comprehension и list comprehension с conditional.

Этот пример аналогичен предыдущему, только conditional выделен желтым.

  1. Создание cashier_3 выделено синим.
  2. Повторение cart выделено зеленым. item создается при запуске цикла for.
  3. При передаче каждого item в cashier_3, проверяется, совпадает ли он с conditional, выделенным желтым.
  4. Обновление cashier_3 с каждым item, выделенное красным, происходит до тех пор, пока элемент удовлетворяет требованиям conditional, выделенным желтым.

Числа больше 100 и нечетные числа

cashier_4 принимает только числа больше 100 и нечетные числа. Как это выполнить?

# Reminder of what cart looks like
cart = [5, 7, 9, 10, 12, 15, 19, 20, 22]

# Non-list comprehension for cashier_4
cashier_4 = []
for item in cart:
item += 100 # add 100 to each item to bring them over 100
if item % 2 == 1: # check to see if they're odd or not
cashier_4.append(item)
print(cashier_4)

# The output is all odd numbers over 100
Output: [105, 107, 109, 115, 119]

Пример с list comprehension.

# List comprehension for cashier_4
cashier_4 = [item+100 for item in cart if item % 2 == 1]
print(cashier_4)

# The output is all odd numbers over 100 (same as above)
Output: [105, 107, 109, 115, 119]

Что дальше?

Это руководство затрагивает лишь основы list comprehensions в Python. Научившись работать с ними, вы поймете, насколько большое значение они имеют при написании краткого и эффективного Python кода.

Код из этой статьи доступен на GitHub.


Перевод статьи Daniel Bourke: Python List Comprehensions in 5-minutes