Como inicializar um dict com chaves de uma lista e valor vazio no Python?

251

Eu gostaria de obter isso:

keys = [1,2,3]

para isso:

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

Existe uma maneira pitônica de fazer isso?

Esta é uma maneira feia de fazer isso:

>>> keys = [1,2,3]
>>> dict([(1,2)])
{1: 2}
>>> dict(zip(keys, [None]*len(keys)))
{1: None, 2: None, 3: None}
Juanjo Conti
fonte

Respostas:

389

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

Na verdade, esse é um método de classe, portanto também funciona para subclasses de dict (como collections.defaultdict). O segundo argumento opcional especifica o valor a ser usado para as chaves (o padrão é None.)

Thomas Wouters
fonte
153
Cuidado ao inicializar para algo mutável: se você chamar, por exemplo, dict.fromkeys([1, 2, 3], [])todas as chaves são mapeadas para a mesma lista, e a modificação de uma modificará todas elas.
charleslparker
8
Inicializar com {k:[] for k in [1, 2, 3]}ainda é seguro.
Aziz Alto
263

ninguém se importava em dar uma solução de compreensão de ditados?

>>> 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}
Adrien Plisson
fonte
32
Eu acredito que foi portado para 2,7
wim
21
Isso é bom e não sofre com o problema de referência que a resposta aceita.
charleslparker
Isso também permite atribuir um valor padrão (por exemplo False).
21415 javascript
Esta é a maneira mais limpa, mais Pythonic em Python3 IMO
Bede Constantinides
4
O uso de um dict-comp também permite que o valor seja o resultado da chamada de uma função (que pode ser passada à chave como argumento, se desejado) - também é um mecanismo muito poderoso.
martineau
56
dict.fromkeys(keys, None)
Dominic Cooney
fonte
2
impressionante, eu queria listas vazias,dict.fromkeys(keys, [])
muon
12
@ muon Isso quase certamente não é o que você quer, veja o comentário de charleslparker .
Gerrit 22/03/19
Funciona no Python versão 2.6.6.
Mike Finch
2
Cuidado: isso inicializará o dict com todos os pontos-chave com o mesmo valor único
Mendi Barel
16
>>> keyDict = {"a","b","c","d"}

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

Resultado:

{'a': [], 'c': [], 'b': [], 'd': []}
Mayur Koshti
fonte
1
Embora esse código possa responder à pergunta, fornecer um contexto adicional a respeito de como e / ou por que ele resolve o problema melhoraria o valor a longo prazo da resposta.
Francesco Menzani
4
o nome keyDicté enganoso, pois a primeira linha de código retorna a set, não a dict.
Bryan Oakley #
10
d = {}
for i in keys:
    d[i] = None
inspectorG4dget
fonte
1
Por que Python lança um erro como TypeError: 'type' object is not iterable:?
FaCoffee 19/10/2015
1
@FrancescoCastellani Porque listé um tipo. A menos que você tem algo parecido list = [], o método acima irá sempre dar-lhe o mesmo erro
smac89
1

Em muitos fluxos de trabalho em que você deseja anexar um valor inicial / padrão para chaves arbitrárias, não é necessário fazer o hash de cada chave individualmente antes do tempo. Você pode usar collections.defaultdict. Por exemplo:

from collections import defaultdict

d = defaultdict(lambda: None)

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

Isso é mais eficiente, pois evita o hash de todas as suas chaves na instanciação. Além disso, defaultdicté uma subclasse de dict, portanto, geralmente não há necessidade de converter novamente em um dicionário comum.

Para fluxos de trabalho em que você precisa de controles sobre chaves permitidas, pode usar dict.fromkeysconforme a resposta aceita:

d = dict.fromkeys([1, 2, 3, 4])
jpp
fonte