Сообщить об ошибке.

Генератор словаря и его использование в Python

В версии Python 3.12 генераторы словарей, списков и множеств теперь встроены, а не создают новый одноразовый функциональный объект для каждого выполнения. Это ускоряет выполнение таких генераторов до двух раз. Подробнее об изменениях в материале "Генератор списка list в Python".

Для создания словарей из произвольных ключей и значений можно использовать короткий синтаксис, который подробно описан в материале о генераторах списков.

>>> {x: x**2 for x in (2, 4, 6)}
# {2: 4, 4: 16, 6: 36}

# словарь генерируется из 2-х списков
>>> {x: y for x, y in zip(['a', 'b', 'c'], [1, 2, 3])}
# {'a': 1, 'b': 2, 'c': 3}

Как и где можно применить генератор словарей.

При помощи генератора словаря можно создать словарь из списка с каким-то значением по умолчанию для значений ключей, тем самым воспроизвести метод dict.fromkeys():

>>> keys = ['key1', 'key2', 'key3', 'key4', 'key5']
>>> def_val = 0
>>> {key: def_val for key in keys}
# {'key1': 0, 'key2': 0, 'key3': 0, 'key4': 0, 'key5': 0}

# то же самое с использованием метода 'dict.fromkeys()'
>>> d = {}
>>> d.fromkeys(keys, def_val)
# {'key1': 0, 'key2': 0, 'key3': 0, 'key4': 0, 'key5': 0}

При создании генераторов словарей следует помнить, что ключами key словаря могут быть только неизменяемые (хешируемые) объекты:

# неизменяемые кортежи могут быть ключами:
>>> {(x, y): x + y for x, y in zip('123', 'abc')}
# {('1', 'a'): '1a', ('2', 'b'): '2b', ('3', 'c'): '3c'}

>>> # а изменяемые списки ключами быть не могут:
>>> {[x, y]: x + y for x, y in zip('123', 'abc')}
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#   File "<stdin>", line 1, in <dictcomp>
# TypeError: unhashable type: 'list'

Поменять местами ключ и значение в словаре.

Меняем местами ключ и значение в словаре, используя генератор словаря. При этом помним, что ключом может быть только неизменяемый объект.

>>> d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> {y: x for x, y in d.items()}
# {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}

Фильтровать словарь по ключу и/или значению.

>>> d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
# отберем элементы словаря, ключи которых имеют значения 'a' или 
# 'c' или 'e', а значения этих ключей должны быть больше 1 
>>> {key: val for key, val in d.items() if key in ('a', 'c', 'e') and val > 1}
# {'c': 3, 'e': 5}

Удалить дубликаты словарей из списка с определенным одинаковым ключом.

Представим, что есть список словарей, в которых одно из значений используется в качестве идентификатора пользователя:

data = [
{'uuid': 0, 'nik': 'alex', 'years': 13},
{'uuid': 1, 'nik': 'fred', 'birthday': 15},
{'uuid': 1, 'nik': 'joy', 'birthday': 8},
{'uuid': 3, 'nik': 'lily', 'birthday': 5},
{'uuid': 4, 'nik': 'moo', 'birthday': 9},
{'uuid': 1, 'nik': 'jack', 'birthday': 10},
]

Стоит задача - удалить дубликаты словарей, содержащие одинаковые значения определенного ключа. В данной ситуации будем удалять словари с одинаковым значение ключа uuid.

Это можно сделать то же при помощи генератора словаря.

>>> new_data = {d['uuid']: d for d in data}.values()
>>> list(new_data)
# [
# {'uuid': 0, 'nik': 'alex', 'years': 13}, 
# {'uuid': 1, 'nik': 'jack', 'birthday': 10}, 
# {'uuid': 3, 'nik': 'lily', 'birthday': 5}, 
# {'uuid': 4, 'nik': 'moo', 'birthday': 9}
# ]

В примере создается словарь, ключами которого являются полe, которое должно быть уникальным (без повторов), затем с помощью метода словаря dict.values() получили все значения из созданного словаря. Так как словарь не может содержать больше одной записи для каждого ключа, то полученный в итоге список словарей не содержит дубликатов, что и требовалось.