Генераторы списков и кортежей в Python

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

Генераторы списков

Основной синтаксис

Генератор списка (list comprehension) позволяет создать новый список, применяя выражение к каждому элементу исходного итерируемого объекта (например, списка, строки или диапазона чисел). Он также позволяет фильтровать элементы по условию.

[выражение for элемент in итерируемый_объект if условие(фильтр)]
  • выражение — это действие, которое выполняется над каждым элементом.
  • элемент — это переменная, которая принимает значения из итерируемого объекта.
  • итерируемый_объект — это объект, по которому можно проходить с помощью цикла (например, список, строка или диапазон чисел).
  • условие(фильтр) — опциональная часть. Если указано, оно фильтрует элементы, оставляя только те, которые соответствуют условию.

Примеры использования генераторов списков

Пример 1: Создание списка квадратов чисел

Рассмотрим задачу создания списка квадратов чисел от 0 до 9.

squares = [x**2 for x in range(10)]
print(squares)

Вывод:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Здесь каждое значение из range(10) возводится в квадрат и добавляется в список squares
Сравним это с эквивалентным кодом без использования генератора:

squares = []
for x in range(10):
    squares.append(x**2)
print(squares)

Как видно, генератор списка значительно упрощает и сокращает код.

Пример 2: Фильтрация списка — создание списка четных чисел

Теперь создадим список только четных чисел от 0 до 19:

evens = [x for x in range(20) if x % 2 == 0]
print(evens)

Вывод:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

Здесь используется условие if x % 2 == 0, которое пропускает только четные числа.

Пример 3: Преобразование списка строк в список их длин

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

words = ["apple", "banana", "cherry"]
lengths = [len(word) for word in words]
print(lengths)

Вывод:

[5, 6, 6]

Этот генератор списка вычисляет длину каждой строки с помощью функции len() и добавляет результат в новый список lengths.

Пример 4: Преобразование списка строк в верхний регистр

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

words = ["hello", "world", "python"]
upper_words = [word.upper() for word in words]
print(upper_words)

Вывод:

['HELLO', 'WORLD', 'PYTHON']

Здесь метод upper() применяется к каждому слову из списка words, и результат добавляется в новый список upper_words.

Пример 5: Создание списка пар (число, его квадрат)

Рассмотрим задачу создания списка кортежей, где каждый кортеж состоит из числа и его квадрата.

pairs = [(x, x**2) for x in range(10)]
print(pairs)

Вывод:

[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49), (8, 64), (9, 81)]

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

Пример 6: Создание списка из первых букв слов

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

words = ["apple", "banana", "cherry"]
first_letters = [word[0] for word in words]
print(first_letters)

Вывод:

['a', 'b', 'c']

Здесь в каждом элементе списка выбирается первый символ строки и добавляется в новый список first_letters.

Пример 7: Генерация списка, умножая элементы на константу

Рассмотрим задачу умножения каждого элемента списка на определенную константу.

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

Вывод:

[10, 20, 30, 40, 50]

Здесь каждый элемент списка numbers умножается на 10, и результат добавляется в новый список multiplied.

Пример 8: Объединение строк из списка в одну строку

Допустим, у нас есть список слов, и мы хотим объединить их в одну строку.

words = ["Python", "is", "awesome"]
sentence = " ".join([word for word in words])
print(sentence)

Вывод:

'Python is awesome'

Здесь с помощью генератора создается список слов, который затем объединяется в одну строку с помощью метода join.

Генераторы кортежей

Генератор кортежей (tuple comprehension) работает по тому же принципу, что и генератор списка, с одной важной разницей: вместо квадратных скобок [] используются круглые скобки ().

Синтаксис

(выражение for элемент in итерируемый_объект if условие)

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

Примеры использования генераторов кортежей

Пример 1: Генерация кортежа квадратов чисел

Допустим, нам нужно создать кортеж квадратов чисел от 0 до 9:

squares_gen = (x**2 for x in range(10))
squares = tuple(squares_gen)
print(squares)

Вывод:

(0, 1, 4, 9, 16, 25, 36, 49, 64, 81)

Здесь генератор создает объект, который затем преобразуется в кортеж с помощью функции tuple().

Пример 2: Генерация кортежа четных чисел

Создадим кортеж только из четных чисел от 0 до 19:

evens_gen = (x for x in range(20) if x % 2 == 0)
evens = tuple(evens_gen)
print(evens)

Вывод:

(0, 2, 4, 6, 8, 10, 12, 14, 16, 18)

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

Пример 3: Генерация кортежа длин строк

Рассмотрим задачу создания кортежа, содержащего длины строк из списка:

words = ["apple", "banana", "cherry"]
lengths_gen = (len(word) for word in words)
lengths = tuple(lengths_gen)
print(lengths)

Вывод:

(5, 6, 6)

Генератор вычисляет длины строк и преобразует их в кортеж.

Пример 4: Генерация кортежа с условиями

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

squares_gen = (x**2 for x in range(10) if x > 3)
squares = tuple(squares_gen)
print(squares)

Вывод:

(16, 25, 36, 49, 64, 81)

Этот пример показывает использование условия if в генераторе кортежа.

Пример 5: Преобразование строк в кортеж верхнего регистра

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

words = ["hello", "world", "python"]
upper_words_gen = (word.upper() for word in words)
upper_words = tuple(upper_words_gen)
print(upper_words)

Вывод:

('HELLO', 'WORLD', 'PYTHON')

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

 

Ветвление выражения с использованием else


Обратите внимание: Мы можем использовать (начиная с Python 2.5) в выражении конструкцию if-else для ветвления финального выражения.

В таком случае:

  • Условия ветвления пишутся не после, а перед for.
  • В данном случае if-else это не фильтр перед выполнением выражения, а ветвление самого выражения, то есть переменная уже прошла фильтр, но в зависимости от условия может быть обработана по-разному!
list_a = [-2, -1, 0, 1, 2, 3, 4, 5]
list_b = [x if x < 0 else x**2 for x in list_a]
# Если x-отрицательное - берем x, в остальных случаях - берем квадрат x
print(list_b)   # [-2, -1, 0, 1, 4, 9, 16, 25]
Никто не запрещает комбинировать фильтрацию и ветвление:
list_a = [-2, -1, 0, 1, 2, 3, 4, 5]
list_b = [x**3 if x < 0 else x**2 for x in list_a if x % 2 == 0]
# вначале фильтр пропускает в выражение только четные значения
# после этого ветвление в выражении для отрицательных возводит в куб, а для остальных в квадрат
print(list_b)   # [-8, 0, 4, 16]

 

Преимущества генераторов списков и кортежей

  • Компактность кода: Генераторы позволяют записывать создание новых списков и кортежей в одну строку, что делает код более кратким и легким для восприятия.
  • Улучшенная производительность: Генераторы позволяют создавать элементы по мере необходимости, особенно это важно для генераторов кортежей, которые не занимают лишнюю память.
  • Гибкость: Возможность добавлять условия фильтрации позволяет создавать более сложные и адаптируемые структуры данных.
  • Читаемость: Использование генераторов делает код более выразительным и понятным.
     

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

Перейти к следующему шагу

Комментарии