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

Генераторы списков. Общие понятия


Содержание


Поиск на других ресурсах:

1. Генераторы списков. Понятия. Общая форма

В языке Python генераторы списков — это реализация цикла for особым образом, при котором генерируется список на основе данных и действий, выполняемых над этими данными. Генераторы списков – это механизм (способ) получения списка на основе некоторого правила (набора правил). Генераторы списков сочетаются с элементами функционального программирования, в т. ч. функциями map() и filter().

Самая общая форма генератора списка с одной переменной-счетчиком выглядит следующим образом

[ expression for variable in sequence [if cond] ]

здесь

  • expression — выражение, которое вычисляется над каждым элементом последовательности sequence. В результате образуется новая последовательность в виде списка;
  • variable — переменная-счетчик, которая по очереди принимает значения из последовательности sequence;
  • sequence — последовательность элементов. Это может быть список, кортеж, множество;
  • cond — условное выражение в операторе if, который может использоваться для образования нового списка согласно условию.

Общая форма любого генератора списка для произвольного количества вложенных циклов имеет вид

[ expression for variable1 in sequence1 [if cond1]
             for variable2 in sequence2 [if cond2]
             ...
             for variableN in sequenceN [if condN] ]

здесь

  • expression — некоторое выражение, вычисляемое над каждым элементом последовательности. Если в выражении фигурирует переменная-счетчик variable1, variable2, variableN, то каждый раз вычисляется значение этой переменной в соответствии с последовательностью sequence1, sequence2, sequenceN;
  • variable1, variable2, variableN — переменные-счетчики, которые поочередно принимают значения в соответствии с последовательностями sequence1, sequence2, sequenceN;
  • sequence1, sequence2, sequenceN — некоторые последовательности (наборы) данных. Этими последовательностями могут быть списки, кортежи, множества;
  • cond1, cond2, condN — условные выражения согласно синтаксису Python, которые используются в операторе if.

 

2. Пример простейшего генератора списка, который обрабатывает список, кортеж и множество

В примере продемонстрировано применение генератора списка для объектов, являющихся списками кортежами и множествами.

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

# Задача.
# Для заданного набора целых чисел сформировать список,
# в котором все элементы возводятся в квадрат

# 1. Решение для списка чисел.
# 1.1. Указанный список чисел
L = [ 34, 76, 12, 35 ]

# 1.2. Записать генератор, получить результат
res_L = [ x*x for x in L ]

# 1.3. Вывести результат
print("res_L = ", res_L) # res_L = [1156, 5776, 144, 1225]

# 2. Решение для кортежа
# 2.1. Указанный кортеж
T = ( 11, 77, 23, 14, 20)

# 2.2. Записать генератор, получить результат
res_T = [ x**2 for x in T ]

# 2.3. Вывести результат
print("res_T = ", res_T) # res_T = [121, 5929, 529, 196, 400]

# 3. Решение для множества
# 3.1. Указанное множество
S = { 2, 2, 8, 3, 3, 4, 5}

# 3.2. Сформировать генератор, который умножит элементы множества на 5
res_S = [ 5*t for t in S ]

# 3.3. Вывести результат,
#     учитывая что элементы в множестве не повторяются
print("res_S = ", res_S) # res_S = [40, 10, 15, 20, 25]

Результат выполнения программы

res_L = [1156, 5776, 144, 1225]
res_T = [121, 5929, 529, 196, 400]

 

3. Замена генератора списка другими средствами языка Python. Примеры

Генератор списка может быть заменен другими средствами языка Python, а именно:

  • использованием базовых операторов языка как for, while, if и тому подобное;
  • функцией map(), если требуется обработка элементов набора без дополнительных условий. Как известно, функция map() отражает некоторую реализованную функцию на последовательность;
  • функцией filter(), если требуется обработка элементов набора согласно некоторой условием if. В этом случае, при формировании нового списка с исходной последовательности, пропускаются элементы значения которых в операторе if возвращает False.

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

 

3.1. Замена генератора списка комбинацией базовых операторов for, while. Пример

Любой алгоритм в Python можно реализовать с использованием стандартных операторов языка for, while, if и тому подобное.

Задача. Задан список слов, в которых встречается символ ‘_’ (подчеркивание). Создать новый список, в котором символ подчеркивания в словах ‘_’ заменить символом ‘ ‘ (пробел).

Решение. Решение с помощью генератора списка

# Решение с помощью генератора списка

# Исходный набор слов
L = [ "ab_cd_e", "abc", "a_b_c", "a__bc_d_", "__" ]

# Сконструировать генератор списка
resL = [ x.replace('_', ' ') for x in L ]

# Вывести новый список
print("resL = ", resL) # resL = ['ab cd e', 'abc', 'a b c', 'a bc d ', '   ']

В вышеприведенном фрагменте генератор списка использует функцию replace() для замены символа.

Решение с использованием цикла for и оператор if

# Исходный набор слов
L = [ "ab_cd_e", "abc", "a_b_c", "a__bc_d_", "__" ]

resL = []
for x in L:
    s = ""
    for c in x:
        if (c == '_'):
            s = s + ' '
        else:
            s = s + c
    resL = resL + [s]

# Вывести результат
print("resL = ", resL)

Возможно и другое решение с использованием функции replace()

# Исходный набор слов
L = [ "ab_cd_e", "abc", "a_b_c", "a__bc_d_", "__" ]

# Сформировать новый список используя функцию replace()
resL = []
for x in L:
    resL = resL + [x.replace('_', ' ')]

# Вывести результат
print("resL = ", resL)

Решение с использованием цикла while, оператора if и функции replace()

# Исходный набор слов
L = [ "ab_cd_e", "abc", "a_b_c", "a__bc_d_", "__" ]

# Сформировать новый список используя
# операторы while, if и функцию replace()
resL = L
i = 0
while i < len(L):
    resL[i] = resL[i].replace('_', ' ')
    i = i+1

# Вывести результат
print("resL = ", resL)

 

3.2. Замена генератора списка функцией map(). Пример

Если на элементы списка нужно наложить некоторую функцию, то для этого можно применить функцию map().

Задача. Задан список слов, в которых встречается символ ‘_’ (подчеркивание). Создать новый список, в котором символ подчеркивания в словах ‘_’ заменить символом ‘ ‘ (пробел).

Решение. Для решения задачи используется функция map(), которая накладывает на каждый элемент списка функцию замены символа replace().

# Заданный набор слов
L = [ "ab_cd_e", "abc", "a_b_c", "a__bc_d_", "__" ]

# Сформировать новый список используя возможности функции map()
resL = list(map((lambda x: x.replace('_', ' ')), L))

# Вывести результат
print("resL = ", resL)

Решение этой задачи с помощью генератора списка описано в п. 4.1.

 

3.3. Замена генератора списка функцией filter(). Пример

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

Задача. Задан набор слов. Сформировать новый список, содержащий слова, длина которых более 4 символов.

Решение. Решение задачи с помощью генератора списка

# Сравнение генераторов списков с функцией filter

# Задан набор слов (строк).
# Выбрать слова, имеющие более 4-х символов.

# Исходный набор слов
L = [ "abcde", "123", "12345", "qwerty", "XXL" ]

# Сформировать новый список используя генератор списков
resL = [ x for x in L if len(x)>4 ] # resL = ['abcde', '12345', 'qwerty']

# Вывести результат
print("resL = ", resL)

Решение задачи с помощью функции filter()

# Исходный набор слов
L = [ "abcde", "123", "12345", "qwerty", "XXL" ]

# Сформировать новый список используя функцию filter()
resL = list(filter((lambda x: len(x)>4), L))

# Вывести результат
print("resL = ", resL)

 

4. Генератор списка, в котором добавляются проверки if. Примеры
4.1. Сформировать список с элементами, кратными 5

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

Решение. Текст программы на языке Python следующий.

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

# Задача.
# Для исходного набора целых чисел сформировать список,
# в котором все элементы набора кратны 5.

# 1. Исходный список чисел
L = [ 34, 76, 12, 35, 20, 18, 11, 55, 5 ]

# 2. Сформировать генератор списка, получить результат
res = [ item for item in L if item % 5 == 0 ]

# 3. Вывести результат
print("res = ", res) # res = [35, 20, 55, 5]

Как видно из вышеприведенного кода, для определения того, кратен ли элемент списка числу 5, используется проверка условия

if item % 5 == 0

Это условие позволяет отфильтровать числа, которые не кратны 5.

Как результат программа выдаст следующий результат

res = [35, 20, 55, 5]

 

4.2. Сформировать список с элементами. Решение с использованием генератора списка, цикла for и функции filter()

Задача. Для заданного списка строк, сформировать новый список, в котором каждая строка имеет две буквы «z». Для решения задачи использовать следующие способы:

  • с помощью генератора списка;
  • с помощью стандартного цикла for;
  • с помощью функции filter().

Решение. Для вычисления количества вхождений символа (подстроки) в строке используется стандартная функция count().

Текст программы, решающей данную задачу, следующий

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

# Задача.
# Для заданного набора строк сформировать новый список,
# в котором все элементы имеют две литеры 'z'

# 1. Исходный список строк
L = [ 'abcz', 'zzz', 'zz', 'azaz', 'abz', 'zabcz', 'azaazab' ]

# 2. Решение с помощью генератора списка.
res1 = [ s for s in L if s.count('z')==2 ] # использовать функцию count()

# 3. Решение с помощью стандартного цикла for
res2 = []
for s in L:
    if s.count('z') == 2:
        res2.append(s)

# 4. Решение с помощью функции filter()
res3 = list(filter((lambda s: s.count('z') == 2), L))

# 5. Вывести результат
print("res1 = ", res1) # res1 = ['zz', 'azaz', 'zabcz', 'azaazab']
print("res2 = ", res2) # res2 = ['zz', 'azaz', 'zabcz', 'azaazab']
print("res3 = ", res3) # res3 = ['zz', 'azaz', 'zabcz', 'azaazab']

Результат выполнения программы

res1 = ['zz', 'azaz', 'zabcz', 'azaazab']
res2 = ['zz', 'azaz', 'zabcz', 'azaazab']
res3 = ['zz', 'azaz', 'zabcz', 'azaazab']

 


Связанные темы