Генератори множин. Генератори словників. Множини та вирази-генератори. Словники та вирази-генератори. Приклади
Перед вивченням даної теми рекомендується ознайомитись з наступною темою:
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'}
⇑