List comprehension в Python
Python известен тем, что даёт разработчикам возможность писать не просто эффективный и лаконичный код. Одним из инструментов для удобного создания списков являются list comprehensions.
new_list = [expression(element) for element in some_obj if condition]
В квадратные скобки мы записываем выражение, которое будет исполняться для каждого элемента в итерируемом объекте. Из результатов этих действий и будет состоять новый список.
Преимущества list comprehension:
Таким кодом вы создаём список с чётными числами до 10:
list_ = [i for i in range(11) if i % 2 == 0] print(list_) # [0, 2, 4, 6, 8, 10]
А так можно создать список со списками внутри (как бы "матрицу"), где в каждом вложенном списке будут цифры 1, 2, 3:
matrix = [[j for j in range(3)] for i in range(3)] print(matrix) # [[0, 1, 2], [0, 1, 2], [0, 1, 2]]
Сравнение list comprehension и цикла for
Цикл for
используется для перебора списков, строк, кортежей и других итерируемых объектов в Python. Рассмотрим небольшой пример.
# Пустой список list_ = [] # Традиционный способ перебора элементов списка for character in 'PythonTalk': list_.append(character) # Вывод списка print(list_) # ['P', 'y', 't', 'h', 'o', 'n', 'T', 'a', 'l', 'k']
А теперь посмотрим на реализацию этой же задачи, но уже с использованием list comprehension:
list_ = [character for character in 'PythonTalk'] print(list_) # ['P', 'y', 't', 'h', 'o', 'n', 'T', 'a', 'l', 'k']
Использование list comprehension позволяет получить более лаконичный и быстро исполняемый код.
Ниже приведен пример, в котором мы напрямую сравниваем время выполнения цикла for
и list comprehension.
# Импортируем необходимый модуль import time # Определяем функцию с циклом for def for_loop(n): result = [] for i in range(n): result.append(i ** 2) return result # Определяем функцию с list comprehension def list_comprehension(n): return [i ** 2 for i in range(n)] # Считаем время выполнения функции for_loop() begin = time.time() for_loop(10 ** 10) end = time.time() print('Время выполнения for_loop:', round(end - begin, 2)) # Считаем время выполнения функции list_comprehension() begin = time.time() list_comprehension(10 ** 10) end = time.time() print('Время выполнения list_comprehension:', round(end - begin, 2))
Время выполнения for_loop: 0.8 Время выполнения list_comprehension: 0.74
Как мы можем видеть, использование list comprehension позволяет немного ускорить выполнение программы.
Вложенные list comprehension
Вложенные list comprehension — это использование одних list comprehension внутри других, что очень напоминает вложенные циклы. Ниже приведен пример использования вложенного цикла.
matrix = [] for i in range(3): # Добавляем пустой подсписок в основной список matrix.append([]) for j in range(5): matrix[i].append(j) print(matrix)
Теперь сделаем то же самое с помощью list comprehension.
matrix = [[j for j in range(5)] for i in range(3)] print(matrix) # [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]
List comprehension и lambda-функции
lambda-функции — способ более лаконичного создания функций в Python. Вместе с list comprehension они создают довольно эффективную комбинацию.
На примере ниже для вывода числовой последовательности мы использовали обычный цикл for
.
numbers = [] for i in range(1, 6): numbers.append(i * 10) print(numbers) # [10, 20, 30, 40, 50]
А так выглядит код, где вместо цикла for
мы использовали list comprehension.
numbers = [i * 10 for i in range(1, 6)] print(numbers) # Вывод: [10, 20, 30, 40, 50]
numbers = list(map(lambda i: i * 10, [i for i in range(1, 6)])) print(numbers) # [10, 20, 30, 40, 50]
Иногда комбинация lambda-функции и list comprehension позволит решить сложную задачу буквально одной строчкой кода.
Условные операторы в list comprehension
В list comprehension мы можем использовать и условные операторы. Посмотрим пример:
list_ = ["Even number" if i % 2 == 0 else "Odd number" for i in range(8)] print(list_) # ['Even number', 'Odd number', 'Even number', 'Odd number', # 'Even number', 'Odd number', 'Even number', 'Odd number']
Можно использовать и вложенные условия:
list_ = [num for num in range(100) if num % 5 == 0 if num % 10 == 0] print(list_) # [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
Ниже приведём еще 6 примеров использования list comprehension для закрепления.
Пример 1. Вывод квадратов чисел от 1 до 10
# Получаем квадраты чисел от 1 до 10 squares = [n ** 2 for n in range(1, 11)] # Выводим квадрат каждого числа print(squares) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Пример 2. Транспонирование матрицы
# Инициализируем матрицу matrix = [[10, 20, 30], [40, 50, 60], [70, 80, 90]] # Генерируем транспонированную матрицу trans = [[i[j] for i in matrix] for j in range(len(matrix))] print(trans) # [[10, 40, 70], [20, 50, 80], [30, 60, 90]]
Пример 3. Смена регистра каждого символа в строке при помощи XOR
# Инициализируем строку string = "PythonTalk" # Смена регистра каждого символа list_ = list(map(lambda i: chr(ord(i) ^ 32), string)) # Вывод элементов списка print(list_) # ['p', 'Y', 'T', 'H', 'O', 'N', 't', 'A', 'L', 'K']
Пример 4. Запись каждой строки в кортежах задом наперёд
# Переворот каждой строки в кортеже list_ = [string[::-1] for string in ('Python', 'Talk')] print(list_) # ['nohtyP', 'klaT']
Пример 5. Создание списка кортежей из двух отдельных списков при помощи zip
names = ['Oleg', 'Kate', 'Kira'] ages = [32, 31, 1] person_tuples = [(name, age) for name, age in zip(names, ages)] print(person_tuples) # [('Oleg', 33), ('Kate', 32), ('Kira', 1)]
Пример 6. Вывод суммы цифр всех нечётных элементов в списке
# Функция сложения всех цифр в числе def digit_sum(n): dsum = 0 for ele in str(n): dsum += int(ele) return dsum # Инициализируем список list_ = [367, 111, 562, 945, 6726, 873] # Используем функцию на нечётных элементах списка new_list = [digit_sum(i) for i in list_ if i & 1] print(new_list) # [16, 3, 18, 18]
Заключение
- List comprehension — эффективное средство создание новых списков на основе существующих итерируемых объектов.
- Как правило, list comprehension позволяют проще и лаконичнее создать список, чем стандартные функции и циклы. И исполняется такой код быстрее.
- Нет необходимости писать длинный код, ведь он изначально получается компактным, понятным и читабельным.
- Любой list comprehnsion может быть заменён циклом
for
, но не каждый циклfor
можно переписать через list comprehension.
Источник: Geeks for Geeks
👉🏻Подписывайтесь на PythonTalk в Telegram 👈🏻