开发者

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

开发者 https://www.devze.com 2022-12-19 16:45 出处:网络
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?

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}
&g开发者_开发百科t;>> dict(zip(keys, [None]*len(keys)))
{1: None, 2: None, 3: None}


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


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: []}


dict.fromkeys(keys, None)


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': []}


Simply iterate and add the values to an empty dictionary:

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


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])


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号