Explain Codes LogoExplain Codes Logo

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

python
dict-comprehensions
defaultdict
mutable-objects
Nikita BarsukovbyNikita Barsukov·Dec 9, 2024
TLDR

You can initialize a dictionary with empty values from a list of keys using dict.fromkeys():

keys_list = ['a', 'b', 'c'] empty_dict = dict.fromkeys(keys_list)

Now in empty_dict each keys_list element is a key with a default None value.

Be mindful of default values and mutable objects

To assign a specific default value, simply throw in a second argument in dict.fromkeys():

empty_dict_with_zeros = dict.fromkeys(keys_list, 0)

"Our keys are well-fed with a meal of zeros!"

However, beware of feeding them mutable default values directly using dict.fromkeys(). This action results in all keys sharing a meal, I mean, the same mutable object! 😲

bad_dict = dict.fromkeys(keys_list, [])

Chaos unfolds when changing one list — it changes them all. Opt for comprehension to ensure well-mannered independent meals:

safe_dict = {key: [] for key in keys_list} # Every key enjoys its meal!

The beauty of Dict Comprehensions

Dict comprehensions add a dollop of elegance to dictionary initialization whilst lending you more control:

keys_list = ['x', 'y', 'z'] empty_dict = {key: None for key in keys_list} # Each key gets its very own 'None'!

"Table for 1 None, please!"

Dict comprehensions guarantee a unique dining experience for each key, even when dining on mutable dishes.

Customized default value? Welcome defaultdict!

When your keys are adventurous eaters, bring in collections.defaultdict. It allows for a custom default factory funtion cooking up fresh mutable objects for each key:

from collections import defaultdict default_list_dict = defaultdict(list) # The 'list' chef is on duty!

Perfect for when you aim to immediately add to an inner collection of a potentially untouched key.

Mindful of side dishes, eh?

When adding value-seasoning to your dictionary, remember the potential side effects. Actions on mutable values leave effects on all table-sharing objects. With comprehension and defaultdict, every key gets its individual dish, safe from collective spice mishaps.

In a hurry? Performance matters

For the time-pressed diner, dict.fromkeys() is a fast and concise chef, skipping needless iterations or dish creations. For large orders or time-critical meals, this is your go-to for initializing a dictionary with immutable default dishes.

Adding flavours to None

Sometimes, you might want your keys to try out dishes other than None, or to start their dining with certain predetermined dishes. Here's an exploration into this culinary adventure:

A shared default

default_value_dict = {key: 'default' for key in keys_list}

All keys start with a delicious 'default' appetizer.

A sequenced meal

sequence_dict = {key: list(range(3)) for key in keys_list}

Each key dives into a pre-planned meal of [0, 1, 2]. Meal planning made easy!

An extra-ordinary culinary experience

complex_dict = {key: SomeClass() for key in keys_list}

If SomeClass is an exotic dish, each key in the dict starts their meal with a unique instance of SomeClass.