322

I'd like to get from this:

keys = [1,2,3]

to this:

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

Is there a pythonic way of doing it?

This is an ugly way to do it:

>>> keys = [1,2,3]
>>> dict([(1,2)])
{1: 2}
>>> dict(zip(keys, [None]*len(keys)))
{1: None, 2: None, 3: None}
evtoh
  • 424
  • 3
  • 8
  • 21
Juanjo Conti
  • 27,061
  • 38
  • 104
  • 130

7 Answers7

484

You can use fromkeys:

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

This is actually a classmethod, so it works for dict-subclasses (like collections.defaultdict) as well. The optional second argument specifies the value to use for the keys (defaults to None.)

Tomerikoo
  • 15,737
  • 15
  • 35
  • 52
Thomas Wouters
  • 125,217
  • 23
  • 144
  • 122
  • 198
    Be careful with initializing to something mutable: If you call, e.g., `dict.fromkeys([1, 2, 3], [])`, all of the keys are mapped to the same list, and modifying one will modify them all. – charleslparker Jun 26 '13 at 16:47
  • 36
    Initializing with `{k:[] for k in [1, 2, 3]}` is still safe though. – Aziz Alto Jun 24 '19 at 16:13
328

nobody cared to give a dict-comprehension solution ?

>>> 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
  • 21,024
  • 4
  • 40
  • 73
77
dict.fromkeys(keys, None)
Dominic Cooney
  • 6,050
  • 1
  • 24
  • 38
17
>>> keyDict = {"a","b","c","d"}

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

Output:

{'a': [], 'c': [], 'b': [], 'd': []}
spongebob
  • 8,552
  • 13
  • 45
  • 80
Mayur Koshti
  • 1,688
  • 15
  • 20
  • 3
    While this code may answer the question, providing additional context regarding _how_ and/or _why_ it solves the problem would improve the answer's long-term value. – spongebob Aug 24 '15 at 12:49
  • 9
    the name `keyDict` is misleading, as the first line of code returns a `set`, not a `dict`. – Bryan Oakley May 23 '16 at 15:55
  • 1
    They probably will be mapped to the same list though – VMAtm Jul 14 '21 at 12:28
15
d = {}
for i in keys:
    d[i] = None
inspectorG4dget
  • 104,525
  • 25
  • 135
  • 234
9

In many workflows where you want to attach a default / initial value for arbitrary keys, you don't need to hash each key individually ahead of time. You can use collections.defaultdict. For example:

from collections import defaultdict

d = defaultdict(lambda: None)

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

This is more efficient, it saves having to hash all your keys at instantiation. Moreover, defaultdict is a subclass of dict, so there's usually no need to convert back to a regular dictionary.

For workflows where you require controls on permissible keys, you can use dict.fromkeys as per the accepted answer:

d = dict.fromkeys([1, 2, 3, 4])
jpp
  • 147,904
  • 31
  • 244
  • 302
0

Just because it's fun how the dict constructor works nicely with zip, you can repeat the default value and zip it to the keys:

from itertools import repeat

keys = [1, 2, 3]
default_value = None

d = dict(zip(keys, repeat(default_value)))
print(d)

Will give:

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

repeat creates an infinite iterator of the element passed to it but as zip stops on the shortest iterable all works well.

Tomerikoo
  • 15,737
  • 15
  • 35
  • 52