Списковые включения в Python (Полное руководство с примерами)

В этом посте мы рассмотрим всё, что вам нужно знать о генераторах списков в Python, используя подробные примеры! Генераторы списков предоставляют изящный, сжатый способ создания, модификации и фильтрации списков в Python.

К концу этого урока вы узнаете:

  • Что такое списки и чем они отличаются от циклов for

  • Как заменить циклы for на понимание списков

  • Как добавить условия в список понятий

  • Как вложить списки в Python

Оглавление

Что такое понимание списка в Python?

Лист компрехеншн - это элегантный и краткий способ определить и создать список в Python. Код написан в формате, который гораздо проще читать. Компрехеншны списков в Python включают в себя квадратные скобки, содержащие выражение, которое выполняется для каждого элемента в итерируемом объекте. Каждый элемент может быть включен и/или трансформирован с условием в компрехеншне.

Что такое список в Python?

Python список - это встроенная структура данных и составной тип данных, что означает, что вы можете использовать его для группировки значений вместе. Списки являются гетерогенными, что означает, что они могут содержать комбинацию различных типов данных, таких как булевы значения, строки, целые числа и т.д.

Python списки отличаются от других составных типов данных Python (например, словарей, кортежей), тем что это упорядоченная коллекция (элементы имеют индекс) и они являются изменяемыми (их можно изменять).

Зачем использовать списки в Python?

Списковые включения представляют собой компактный способ создания списков. Одно из их главных применений - создание списков, в которых каждый элемент является результатом применения операции к каждому элементу итерируемого объекта, или для создания уменьшенного набора элементов данного списка.

Преимущества понимания списка

Списковые включения в Python являются более питоническим способом создания, модификации и фильтрации списков.

Это невероятно полезно, поскольку представляет собой единый инструмент для выполнения множества задач, вместо того чтобы полагаться на циклы for, функции map() или функции filter(). Это замечательно, так как позволяет применить один метод, вместо того чтобы пытаться подогнать использование под конкретный сценарий.

Списковые включения также, во многих случаях, проще для чтения, чем циклы for. Они не требуют создания пустого списка или добавления элементов в новый список.

Как написать понимание списка?

Списочные включения в Python следуют структуре: [Выражение для Элемента в Итерируемом].

  • Выражение может быть любым выражением - одним элементом, функцией, примененной к элементу и т.д.

  • Элемент — это элемент в итерируемом объекте.

  • Итерируемый объект — это объект, по которому можно выполнять итерацию (например, список, кортеж и т. д.)

Давайте посмотрим, как это выглядит на примере:

В приведенном выше примере мы проходим по списку, который содержит числа от 1 до 5, и возводим каждое число в квадрат. Если бы мы записали это на Python коде, это выглядело бы так:

squares = [x ** 2 for x in [1,2,3,4,5]
print(squares)

#Returns [1,4,9,16,25]

Понимание списка и цикл For

List comprehensions предлагают краткий синтаксис для замены циклов for, используемых для итерации по элементам. Циклы for в Python часто используются для создания списков из других итерируемых объектов. Однако их написание и выполнение занимает больше времени.

Давайте рассмотрим пример цикла for. Ниже мы используем цикл for для создания списка от 0 до 9. Для этого мы будем:

  1. Создайте (инициализируйте) пустой список.

  2. Перебор элементов в диапазоне элементов и

  3. Добавьте каждый элемент в конец списка.

numbers = []
for i in range(10):
	numbers.append(i)
print(numbers)

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

numbers = [i for i in range(10)]
print(numbers) 

Оба эти фрагмента кода возвращают:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Важно отметить, что каждое выражение списка может быть написано в виде цикла for, но не каждый цикл for может быть выражением списка. Всегда стремитесь к читабельности!

Почему понимание списков происходит быстрее, чем циклы for?

Списковые включения работают быстрее циклов for, поскольку они оптимизированы для интерпретации по предсказуемому шаблону, не требуют повторного поиска списка при каждом обращении и не нуждаются в выполнении операции добавления во время каждого прохода.

Сравнение списков и функций Lambda и Map()

Лямбда-функции являются анонимными функциями в Python, что означает, что они используются только в момент их создания. Эти функции обычно используются вместе с функцией map(), особенно для изменения списков.

Давайте рассмотрим, как функции map и lambda могут быть использованы для изменения списка. В примере мы будем переводить список весов из килограммов в фунты.

weights_kg = [1.0, 3.5, 4.2]
weights_lbs = list(map(lambda x:float(2.2) * x, weights_kg))
print(weights_lbs)

Чтобы написать это в виде понимания списка, мы могли бы написать следующий код:

weights_kg = [1.0, 3.5, 4.2]
weights_lbs = [x * 2.2 for x in weights_kg]
print(weights_lbs)

Оба из них возвращают следующее:

[2.2, 7.7, 9.24]

Понимание списка Python, If Else (условия)

Условные операторы могут значительно улучшить понимание списков в Python. Они выполняют две основные функции:

  1. Чтобы отфильтровать список и

  2. Чтобы изменить элементы в списке.

В зависимости от того, для чего вы хотите использовать условные выражения if else в понимании списка Python, условие ставится в разное место.

Изменение списка с помощью оператора List понимание If Else

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

новый_список = [выражение (если-иначе утверждение) для элемента в итерируемом объекте]

Давайте попробуем это на примере. Мы возьмем список с числами от 1 до 5 и обозначим элементы как четные или нечетные:

old_list = [1,2,3,4,5]
new_list = ['even' if x % 2 == 0 else 'odd' for x in old_list]
print(new_list)

Python вычисляет остаток от деления числа на 2 – если полученное значение равно 0, к новому списку добавляется строка ‘четное’. Если значение не равно 0, добавляется ‘нечетное’.

Это возвращает следующее:

['odd', 'even', 'odd', 'even', 'odd']

Фильтрация списка с использованием генератора списка и условного оператора

Чтобы отфильтровать список, условие ставится в конец генератора списка.

новый_список = [выражение за элемент в итерируемом (если утверждение)]

Давайте попробуем это на другом примере. Если у нас есть список чисел от 1 до 5 и мы хотим отфильтровать все четные числа, мы могли бы написать:

old_list = [1,2,3,4,5]
new_list = [x for x in old_list if x % 2 == 1]
print(new_list)

Python оценивает остаток от деления каждого элемента списка на 2 и, если возвращаемое значение равно 1, то исходный элемент добавляется в новый список.

Это возвращает следующее:

[1, 3, 5]

Множественные условия if в списках

В Python возможно применять несколько условий if внутри генераторов списков, объединяя их вместе.

Давайте рассмотрим пример. Если бы мы хотели сгенерировать список чисел, которые делятся на 2 и на 5, мы могли бы сделать это с помощью цикла for:

new_list = []
for i in range(1, 101):
    if i % 2 == 0:
        if i % 5 == 0:
            new_list.append(i)
print(new_list)

Для того чтобы сделать это с помощью понимания списков, мы можем значительно сократить количество кода:

new_list = [i for i in range(1, 101) if i % 2 == 0 if i % 5 == 0]
print(new_list)

Это возвращает следующее:

[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

Понимание вложенных списков

Вложенные списковые включения также могут быть особенно полезны при работе со списками списков. Это может включать в себя создание списков списков, их преобразование в обычные списки или транспонирование.

Например, если бы у нас был список списков, похожий на список ниже:

nested_list = [[1,2,3],[4,5,6],[7,8,9]]

Если бы нам хотелось преобразовать это в плоский список, мы могли бы сделать это с помощью цикла for:

nested_list = [[1,2,3],[4,5,6],[7,8,9]]
flat_list = []
for list in nested_list:
	for item in list:
		flat_list.append(item)
print(flat_list)

Чтобы сделать это с помощью понимания списка, мы можем написать:

nested_list = [[1,2,3],[4,5,6],[7,8,9]]
flat_list = [i for j in nested_list for i in j]
print(flat_list)

Оба из них возвращаются:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

Пример. Поиск общих элементов в двух списках с использованием списков.

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

Давайте сначала посмотрим, как это можно сделать с использованием циклов for:

list1 = ['apple', 'orange', 'banana', 'grape']
list2 = ['grapefruit', 'apple', 'grape', 'pear']
common_items = []

for i in list1:
	for j in list2:
		if i == j:
			common_items.append(j)
print(common_items)

Чтобы сделать это с помощью генератора списков, мы можем просто написать:

list1 = ['apple', 'orange', 'banana', 'grape']
list2 = ['grapefruit', 'apple', 'grape', 'pear']

common_items = [i for i in list1 if i in list2]
print(common_items)

Оба эти способа возвращают один и тот же список, но список, созданный с помощью генератора списка, гораздо легче понять!

['apple', 'grape']

Когда не следует использовать списки

Списковые включения замечательны, потому что они по-питоновски - до тех пор, пока это не становится не так. Python стремится к читабельности (см. Zen Python). Хотя в большинстве случаев списковые включения оказываются более читабельными, чем другие методы, такие как циклы for, они также могут стать довольно сложными. В этих случаях может быть лучше использовать другой метод для улучшения будущей читабельности.

Важно отметить, что любое включение списка можно записать в виде цикла for, но не каждый цикл for может быть преобразован в включение списка. Всегда стремитесь к читабельности!

Важно не использовать слишком длинные списковые включения вместо простых циклов for.

Заключение: понимание списков Python

В этом посте мы научились использовать понимания списков в Python для создания, изменения и фильтрации списков. В частности, мы узнали:

  • Понимание преимущества списков,

  • Как использовать списки для замены циклов for и функций map(),

  • Как добавить условные выражения в список,

  • Как использовать вложенные списки и, что немаловажно,

  • Когда не следует использовать списков.

Спасибо за чтение! Если вам понравилось это руководство, ознакомьтесь с другими нашими руководствами по Python, включая подробный обзор генераторов словарей.

Дополнительные ресурсы

Чтобы узнать больше о связанных темах, ознакомьтесь с обучающими материалами ниже:

  • Словарь Python (с примерами)

  • Списки Python: полный обзор

  • Учебное пособие по циклу Python For – все, что вам нужно знать!

  • Словари Python: полный обзор

Last updated