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

Генератори списків. Загальні поняття


Зміст


Пошук на інших ресурсах:

1. Генератори списків. Поняття. Загальна форма

Генератори списків – це реалізація циклу 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']

 


Споріднені теми