В версии 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()
получили все значения из созданного словаря. Так как словарь не может содержать больше одной записи для каждого ключа, то полученный в итоге список словарей не содержит дубликатов, что и требовалось.