Как инициализировать dict с ключами из списка и пустым значением в Python?

251

Я хотел бы получить от этого:

keys = [1,2,3]

к этому:

{1: None, 2: None, 3: None}

Есть ли питонский способ сделать это?

Это ужасный способ сделать это:

>>> keys = [1,2,3]
>>> dict([(1,2)])
{1: 2}
>>> dict(zip(keys, [None]*len(keys)))
{1: None, 2: None, 3: None}
Хуанхо Конти
источник

Ответы:

390

dict.fromkeys([1, 2, 3, 4])

На самом деле это метод класса, поэтому он работает и для подклассов dict (например collections.defaultdict). Необязательный второй аргумент указывает значение, используемое для ключей (по умолчанию None.)

Томас Воутерс
источник
154
Будьте осторожны с инициализацией чего-то изменчивого: если вы вызываете, например, dict.fromkeys([1, 2, 3], [])все ключи отображаются в один и тот же список, и изменение одного из них изменит их все.
charleslparker
8
Инициализация с {k:[] for k in [1, 2, 3]}все еще безопасна, хотя.
Азиз Альто
263

никто не заботился о том, чтобы дать решение для всестороннего понимания?

>>> keys = [1,2,3,5,6,7]
>>> {key: None for key in keys}
{1: None, 2: None, 3: None, 5: None, 6: None, 7: None}
Адриен Плиссон
источник
32
Я считаю , что это было портированном 2,7
Вим
21
Это хорошо и не страдает от ссылочной проблемы, которую делает принятый ответ.
charleslparker
Это также позволяет вам назначить значение по умолчанию (например False).
neverendingqs
Это самый чистый, самый Pythonic путь в Python3 IMO
Беда Константинидс
4
Использование dict-comp также позволяет значению быть результатом вызова функции (которой при желании можно передать ключ в качестве аргумента) - так что это очень мощный механизм.
Мартино
56
dict.fromkeys(keys, None)
Доминик Куни
источник
2
здорово, я хотел пустые списки,dict.fromkeys(keys, [])
мюон
12
@muon Это почти наверняка не то, что вы хотите, см. комментарий charleslparker .
Gerrit
Работает в Python версии 2.6.6.
Майк Финч,
2
Осторожно: это инициализирует dict со всеми ключевыми точками на одно и то же значение
Менди Барел
16
>>> keyDict = {"a","b","c","d"}

>>> dict([(key, []) for key in keyDict])

Вывод:

{'a': [], 'c': [], 'b': [], 'd': []}
Маюр Кошти
источник
1
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшит долгосрочную ценность ответа.
Франческо Мензани
4
имя keyDictвводит в заблуждение, так как первая строка кода возвращает a set, а не a dict.
Брайан Оукли
10
d = {}
for i in keys:
    d[i] = None
inspectorG4dget
источник
1
Почему Python выдает ошибку вроде TypeError: 'type' object is not iterable:?
FaCoffee,
1
@FrancescoCastellani Потому listчто это тип. Если у вас нет чего-то подобного list = [], описанный выше метод всегда выдаст вам одну и ту же ошибку
smac89
1

Во многих рабочих процессах, где вы хотите прикрепить значение по умолчанию / начальное значение для произвольных ключей, вам не нужно заранее хешировать каждый ключ отдельно. Вы можете использовать collections.defaultdict. Например:

from collections import defaultdict

d = defaultdict(lambda: None)

print(d[1])  # None
print(d[2])  # None
print(d[3])  # None

Это более эффективно, избавляет от необходимости хэшировать все ваши ключи при создании экземпляра. Более того, defaultdictэто подкласс dict, поэтому обычно нет необходимости преобразовывать обратно в обычный словарь.

Для рабочих процессов, где вам требуются элементы управления разрешенными ключами, вы можете использовать dict.fromkeysсогласно принятому ответу:

d = dict.fromkeys([1, 2, 3, 4])
JPP
источник