How to initialize a dict with keys from a list and empty value in Python?

Question:

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}
Asked By: Juanjo Conti

||

Answers:

dict.fromkeys directly solves the problem:

>>> dict.fromkeys([1, 2, 3, 4])
{1: None, 2: None, 3: None, 4: None}

This is actually a classmethod, so it works for dict-subclasses (like collections.defaultdict) as well.

The optional second argument, which defaults to None, specifies the value to use for the keys. Note that the same object will be used for each key, which can cause problems with mutable values:

>>> x = dict.fromkeys([1, 2, 3, 4], [])
>>> x[1].append('test')
>>> x
{1: ['test'], 2: ['test'], 3: ['test'], 4: ['test']}

If this is unacceptable, see How can I initialize a dictionary whose values are distinct empty lists? for a workaround.

Answered By: Thomas Wouters
dict.fromkeys(keys, None)
Answered By: Dominic Cooney

Simply iterate and add the values to an empty dictionary:

d = {}
for i in keys:
    d[i] = None
Answered By: inspectorG4dget

Use a dict comprehension:

>>> 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}

The value expression is evaluated each time, so this can be used to create a dict with separate lists (say) as values:

>>> x = {key: [] for key in [1, 2, 3, 4]}
>>> x[1] = 'test'
>>> x
{1: 'test', 2: [], 3: [], 4: []}
Answered By: Adrien Plisson

A list comprehension can be used to build a list of key-value pairs, which can then be passed to the dict constructor. Thus:

>>> keys = {"a", "b", "c", "d"}
>>> d = dict([(key, []) for key in keys])
>>> d
{'d': [], 'c': [], 'a': [], 'b': []}

The value expression is evaluated each time, creating separate lists in the above example:

>>> d['a'].append('test')
>>> d
{'d': [], 'c': [], 'a': ['test'], 'b': []}
Answered By: Mayur Koshti

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])
Answered By: jpp

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.

Answered By: Tomerikoo
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.