Python. Генератори множин. Генератори словників

Генератори множин. Генератори словників. Множини та вирази-генератори. Словники та вирази-генератори. Приклади

Перед вивченням даної теми рекомендується ознайомитись з наступною темою:

 

1. Генератори множин. Поняття. Загальна форма

Крім генераторів списків у мові Python існують також генератори множин та генератори словників. Ці нові форми генераторів з’явились починаючи з версії Python 3.0. Генератори множин дозволяють отримувати множини (set) на основі заданого виразу, який формується з деякої послідовності.

Загальна форма використання генератора множини має вигляд:

resSet = { f(x) for x in sequence if condition(x) }

тут

  • resSet – результуюча множина
  • f(x) – довільний вираз;
  • x – змінна, яка по черзі приймає значення з послідовності sequence;
  • sequence – деяка послідовність значень;
  • condition(x) – умова, яка застосовується до змінної x.

Існує також спрощена загальна форма генератора множини. У цій формі відсутня умова if:

{ f(x) for x in sequence }

Обидві вищенаведені форми видають результат повністю у вигляді множини. Ці форми можуть бути замінені відповідно конструкціями

resSet = set ( f(x) for x in sequence if condition(x) )

або

resSet = set ( f(x) for x in sequence )

 

2. Приклади використання генераторів множин
2.1. Генерування множини випадкових чисел згідно з умовою

Умова задачі. З допомогою генератора множини утворити множину з чисел, які піднесені до степеня 3.

Розв’язок.

# Генератор множини

# Утворити множину з 10 чисел, які піднесені до степеня 3
res = { x*x*x for x in range(1, 11) }
print("res = ", res)

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

res = {64, 1, 512, 8, 1000, 343, 216, 729, 27, 125}

 

2.2. Згенерувати множину на основі заданого списку

Умова задачі. Задано список L. Використовуючи генератор множин потрібно створити множину S на основі списку L.

# Генератор множин.
# З заданого списку утворити множину
L = [ 2.88, 3.5, 1.7, -2.4, 65.8, 2.88, 2.88, 1.7, -2.4, 3.2 ]
S = { item for item in L }
print("S = ", S)

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

S = {3.5, 65.8, -2.4, 2.88, 1.7, 3.2}

 

2.3. Згенерувати множину парних елементів зі списку

Умова задачі. Задано список цілих чисел. З допомогою генератора множин утворити множину, що містить елементи списку, які є парними.

Розв’язок.

# Генератор множин.
# З заданого списку утворити множину, що містить парні елементи
L = [ 2, 8, 5, 2, 8, 4, 3, 3, 2, 8, 6, 7, 11, 2 ]
S = { item for item in L if item%2 == 0 }
print("S = ", S)

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

S = {8, 2, 4, 6}

 

3. Генератори словників. Особливості. Загальна форма

Генератори словників введені в Python починаючи з версії 3.0. З допомогою цих генераторів можна утворювати словники за наступною загальною формою

resDict = { key:val for (key, val) in zip(keys, vals) if condition }

тут

  • resDict – об’єкт, що є словником;
  • (key:val) – пара, в якій key – ключ, val – значення, що отримується за ключем;
  • sequence – деяка послідовність. Ця послідовність може бути утворена функцією zip() або іншою функцією;
  • condition – умова, на основі якої вибираються значення з послідовності sequence.

Вищенаведена загальна форма може мати спрощений вигляд, в якому відсутня умова if

resDict = { key:val for (key, val) in zip(keys, vals) }

З допомогою функції dict() можна замінити обидві загальні форми наступними викликами

resDict = dict(zip(keys, values))

тут

  • keys – набір ключів у словнику;
  • values – набір значень що відповідають ключам keys.

 

4. Приклади створення словників на основі генераторів словників
4.1. Сформувати словник на основі діапазону значень range()

Умова задачі. Задано послідовність парних чисел від 0 до 10 включно. З заданої послідовності утворити словник, що містить пари (key:value) в яких значення key удвічі більше за значення value.

Розв’язок.

# Генератори словників
# На основі діапазону значень утворити словник

# Задати набір парних чисел 0, 2, 4, 8, 10
R = range(0, 11, 2)

# Утворити словник
D = { t: t+t for t in R }

# Вивести результат
print(D)

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

{0: 0, 2: 4, 4: 8, 6: 12, 8: 16, 10: 20}

 

4.2. Сформувати словник на основі списку чисел

Умова задачі. На основі списку чисел Values утворити словник в якому кожен ключ є номером позиції значення зі списку Values. Іншими словами, пронумерувати значення Values. Вважати, що позиції нумеруються з 1.

Розв’язок. Для отримання словника потрібно використати функцію zip(), яка об’єднує дві послідовності Keys та Values.

# Генератори словників
# Задача. Пронумерувати значення у списку
# Задано список чисел - це будуть значення values
Values = [ 1.7, 2.2, 0.4, 3.8, 2.2 ]

# На основі списку сформувати ключі keys
Keys = range(1, len(Values))

# Спосіб 1. Утворити словник та вивести його
D = { key:val for (key, val) in zip(Keys, Values) }
print(D)

# Спосіб 2. Використання функції dict()
D2 = dict(zip(Keys, Values))
print(D2)

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

{1: 1.7, 2: 2.2, 3: 0.4, 4: 3.8}
{1: 1.7, 2: 2.2, 3: 0.4, 4: 3.8}

 

4.3. Сформувати словник на основі списку рядків, в яких довжина більше заданого значення

Умова задачі. Задано список рядків S. На основі списку S сформувати словник D, в якому ключі keys є позицією відповідного рядка списку. У словник включити тільки ті елементи зі списку S, довжина яких більше 4 символи.

Розв’язок.

# Задача. У словник включити рядки, які мають довжину більше 4 символи.

# Задано список рядків
S = [ 'abc', 'ab', 'abcd', 'jklmn', 'jprst', 'xyz' ]

# Утворити новий список з рядками, довжина яких більше 4
S2 = [ t for t in S if len(t)>4 ]

# Утворити список номерів рядків згідно з умовою
L = range(1, len(S2)+1)

# Утворити словник
D = { k:v for (k, v) in zip(L, S2) }

# Вивести словник
print(D)

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

{1: 'jklmn', 2: 'jprst'}

 

4.4. Сформувати словник на основі множини унікальних рядків. Значеннями словника є довжини рядків

Умова задачі. Задано множину рядків S. На основі множини S утворити словник D в якому:

  • ключами keys є рядки з множини S;
  • значеннями values є відповідно довжина кожного рядка.

Розв’язок.

# Задано множину рядків
S = { 'abc', 'ab', 'abcd', 'jklmn', 'jprst', 'xyz' }

# На основі множини S сформувати значення з допомогою генератора списків.
# Кожне значення це довжина відповідного рядка в множині S
L = [ len(t) for t in S ]

# Спосіб 1. Утворити словник та вивести його
D = { k:v for (k, v) in zip(S, L) }
print(D)

# Спосіб 2. Використання функції dict()
D2 = dict(zip(S, L))
print(D2)

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

{'abc': 3, 'ab': 2, 'abcd': 4, 'jklmn': 5, 'jprst': 5, 'xyz': 3}
{'abc': 3, 'ab': 2, 'abcd': 4, 'jklmn': 5, 'jprst': 5, 'xyz': 3}

 

4.5. Сформувати словник з кортежу чисел, в якому значення є додатніми

Умова задачі. Задано кортеж. Створити словник, в якому пари ключ:значення формуються за наступними правилами:

  • значеннями є тільки додатні числа;
  • ключі є порядковими номерами відповідних значень.

Розв’язок.

# Задача. Сформувати словник на основі кортежу
# Задано кортеж
T = ( -8.2, 3.4, 1.6, 12, 12.5, -4.2, 0.8, 7, 7 )

# Сформувати словник
D = { key:value for (key, value) in zip(range(1, len(T)+1), T) if value>0 }

# Вивести словник
print(D)

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

{2: 3.4, 3: 1.6, 4: 12, 5: 12.5, 7: 0.8, 8: 7, 9: 7}

 

5. Множини, словники і вирази-генератори

Генератори множин та генератори словників конструюють результат повністю. Якщо потрібно щоб значення з множини чи словника постачались по одному за вимогою, тоді формуючий вираз потрібно взяти в круглі дужки ( ).

Використання виразу-генератора для постачання даних до множини реалізується наступним чином

IterObjSet = ( expression )
S = set(IterObjSet)

тут

  • expression – вираз-генератор;
  • IterObjSet – ітерований об’єкт, який постачає дані за вимогою;
  • S – результуюча множина.

Використання виразу-генератора для постачання даних до словника може бути таким

IterObjDict = ( expression )
D = dict(IterObjDict)

D = { key:value for (key, value) in zip( Keys, Values) }

Якщо використовувати ітерований об’єкт для генерування словника з допомогою генератора, то можливий наступний код

D = { key:value for (key, value) in zip( Keys(IterObjDict), Values(IterObjDict)) }

тут

  • key:value – пара значень, які отримуються відповідно з послідовностей Keys та Values;
  • Keys(IterObjDict) – послідовність ключів, яка може бути отримана з IterObjDict. Можлива ситуація, коли послідовність ключів Keys формується незалежно від IterObjDict;
  • Values(IterObjDict) – послідовність значень, яка може бути отримана з IterObjDict. Можливий випадок, коли послідовність значень Values формується незалежно від IterObjDict;
  • D – результуючий словник.

 

6. Приклад, що демонструє застосування виразів-генераторів у поєднанні з множинами

У прикладі демонстративно створюється список L цілочисельних елементів. Потім на основі списку L створюється ітерований об’єкт IterObj, який буде постачати дані за вимогою. Об’єкт створюється з допомогою виразу-генератора.
За допомогою методу next() з ітерованого об’єкту витягуються перші 3 елементи та додаються до множини S. Елементи, що залишились, додаються до множини S2.

# Множини і вирази-генератори
# Заданий список.
L = [ 2, 8, 3, 4, 6, 1, 7, 9 ]

# 1. Утворити ітерований об'єкт, що містить елементи зі списку L
IterObj = ( item for item in L ) # вираз-генератор

# 2. Утворити множину, на основі ітерованого об'єкту IterObj
# 2.1. Створити пусту множину S
S = set()

# 2.2. Витягнути по черзі 3 елементи з IterObj
# Витягнути перший елемент з IterObj та додати його до множини S
t = next(IterObj)
S = S | {t};

# Додати другий елемент до множини S
t = next(IterObj)
S = S | {t};

# Додати третій елемент до множини S
t = next(IterObj)
S = S | {t}

# Вивести множину S
print("S = ", S)

# Вивести елементи, що залишились в IterObj
S2 = set(IterObj)
print("S2 = ", S2)

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

S = {8, 2, 3}
S2 = {1, 4, 6, 7, 9}

 

7. Приклад, що демонструє застосування виразів-генераторів для постачання значень словникам

Умова задачі. Задано список рядків L. На основі списку L утворити словник. У словнику ключі є номерами позицій відповідного рядка, а значення є цими рядками.

Розв’язок.

# Словники і вирази-генератори
# 1. Заданий список рядків
L = [ 'abc', 'abcd', 'fgh', 'jklmn', 'wxy' ]

# 2. Отримати довжину списку
length = len(L)

# 1. Утворити ітерований об'єкт, що містить елементи зі списку L
IterObj = ( item for item in L ) # вираз-генератор

# 2. Утворити словник, який містить перші 2 рядка зі списку L
# 2.1. Сформувати пустий словник
D = {}

# 2.2. Витягнути перший елемент з IterObj і додати його до словника
t = next(IterObj)
D[0] = t # тут пара (key:value) => (0 : t)

# 2.3. Витягнути другий елемент з IterObj
t = next(IterObj)
D[1] = t # (key:value) => (1 : t)

# 2.4. Вивести словник D
print(D)

# 3. Утворити другий словник з елементів, що залишились в IterObj
# 3.1. Отримати діапазон ключів
R = range(2, length+1)

# 3.2. Сформувати словник
D2 = { key:value for (key, value) in zip(range(2, length+1), IterObj) }

# 3.3. Вивести словник
print(D2)

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

{0: 'abc', 1: 'abcd'}
{2: 'fgh', 3: 'jklmn', 4: 'wxy'}