Генераторы списков и кортежей — это мощные и гибкие инструменты в 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')
Далее я не вижу смысла рассматривать точно такие же выражения для кортежа, ибо они одинаковы со списком, это я надеюсь вы понимаете.
Обратите внимание: Мы можем использовать (начиная с Python 2.5) в выражении конструкцию if-else для ветвления финального выражения.
В таком случае:
for
.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 более элегантным, кратким и эффективным. Освоив генераторы, вы сможете значительно улучшить производительность и читаемость своих программ, особенно при работе с большими наборами данных. Практикуйтесь, используя генераторы в разных контекстах, и вы вскоре оцените все их преимущества.