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 – значение, получаемое по ключу key;
  • 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'}

 


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