To initialize a dictionary in Python, write the keys and values in curly braces ({"a": 1}), start with an empty dictionary ({} or dict()), or build one from existing data with dict(zip(keys, values)) or a dictionary comprehension. To give every key the same starting value, such as 0, use dict.fromkeys(keys, 0):
scores = dict.fromkeys(["math", "science", "english"], 0)
print(scores)
Output:
{'math': 0, 'science': 0, 'english': 0}
Every example was run with Python 3.12.5; the output shown is from those runs.
8 ways to initialize a dictionary
a = {} # empty dictionary
b = dict() # also empty
c = {"apple": 3, "banana": 5} # literal with keys and values
d = dict(apple=3, banana=5) # keyword arguments (keys must be valid names)
e = dict([("apple", 3), ("banana", 5)]) # from a list of (key, value) pairs
f = dict(zip(["apple", "banana"], [3, 5])) # from two lists
g = {fruit: 0 for fruit in ["apple", "banana"]} # dictionary comprehension
h = dict.fromkeys(["apple", "banana"], 0) # same value for every key
for name, value in zip("abcdefgh", [a, b, c, d, e, f, g, h]):
print(name, value)
Output:
a {}
b {}
c {'apple': 3, 'banana': 5}
d {'apple': 3, 'banana': 5}
e {'apple': 3, 'banana': 5}
f {'apple': 3, 'banana': 5}
g {'apple': 0, 'banana': 0}
h {'apple': 0, 'banana': 0}
| Method | Use it when |
|---|---|
{} / dict() | You’ll add keys later |
{"k": v} | You know the keys and values now |
dict(k=v) | Keys are simple names (no spaces, not numbers) |
dict(pairs) | You have a list of (key, value) tuples |
dict(zip(keys, values)) | Keys and values are in two lists |
{k: f(k) for k in ...} | Values are computed, or each key needs its own list/dict |
dict.fromkeys(keys, value) | Every key gets the same immutable value (0, None, “”) |
More on building from two lists: create a dictionary from two lists.
Initialize a dictionary with 0
Starting every key at 0 is the classic setup for counting:
words = "the cat and the hat and the bat".split()
counts = dict.fromkeys(set(words), 0) # every word starts at 0
for w in words:
counts[w] += 1
print(dict(sorted(counts.items())))
Output:
{'and': 2, 'bat': 1, 'cat': 1, 'hat': 1, 'the': 3}
Without the initialization, the first += 1 fails because the key doesn’t exist yet:
counts = {}
counts["the"] += 1
Output:
KeyError: 'the'
Let Python create the 0 for you
defaultdict(int) creates a missing key with int(), which is 0, the first time you use it. For counting, Counter does everything in one call (both are part of the collections module):
from collections import Counter, defaultdict
words = "the cat and the hat and the bat".split()
counts = defaultdict(int) # missing keys start at int() == 0
for w in words:
counts[w] += 1
print(dict(counts))
print(Counter(words)) # the same count in one line
Output:
{'the': 3, 'cat': 1, 'and': 2, 'hat': 1, 'bat': 1}
Counter({'the': 3, 'and': 2, 'cat': 1, 'hat': 1, 'bat': 1})
defaultdict(int) and Counter run in the Command Prompt.Or use dict.get(key, 0) with a normal dictionary:
counts = {}
for w in "a b a c a".split():
counts[w] = counts.get(w, 0) + 1 # 0 if the key isn't there yet
print(counts)
Output:
{'a': 3, 'b': 1, 'c': 1}
Initialize a dictionary with keys and values
keys = ["name", "age", "city"]
values = ["Ann", 34, "Boston"]
person = dict(zip(keys, values))
print(person)
person_default = dict.fromkeys(keys) # value defaults to None
print(person_default)
Output:
{'name': 'Ann', 'age': 34, 'city': 'Boston'}
{'name': None, 'age': None, 'city': None}
dict.fromkeys(keys) without a value gives every key None, which is useful when you’ll fill in the values later.
The dict.fromkeys() trap: shared lists
fromkeys() puts the same object under every key. That’s fine for 0 or None, but not for a list or dict:
students = ["ann", "bob", "cy"]
grades = dict.fromkeys(students, []) # ONE list shared by every key
grades["ann"].append(90)
print(grades)
print("same list?", grades["ann"] is grades["bob"])
Output:
{'ann': [90], 'bob': [90], 'cy': [90]}
same list? True
Use a dictionary comprehension so each key gets its own list:
students = ["ann", "bob", "cy"]
grades = {s: [] for s in students} # a new list for each key
grades["ann"].append(90)
print(grades)
print("same list?", grades["ann"] is grades["bob"])
Output:
{'ann': [90], 'bob': [], 'cy': []}
same list? False
fromkeys(keys, []): one list for all keys. Comprehension: one list per key.Initialize a dictionary of lists
from collections import defaultdict
orders = [("ann", "tea"), ("bob", "coffee"), ("ann", "cake")]
by_customer = defaultdict(list) # missing keys start as []
for customer, item in orders:
by_customer[customer].append(item)
print(dict(by_customer))
manual = {}
for customer, item in orders:
manual.setdefault(customer, []).append(item) # without defaultdict
print(manual)
Output:
{'ann': ['tea', 'cake'], 'bob': ['coffee']}
{'ann': ['tea', 'cake'], 'bob': ['coffee']}
More examples: Python dictionary of lists.
Initialize a nested dictionary
import json
stores = ["north", "south"]
months = ["jan", "feb"]
sales = {store: {month: 0 for month in months} for store in stores}
sales["north"]["jan"] = 120
print(json.dumps(sales, indent=2))
Output:
{
"north": {
"jan": 120,
"feb": 0
},
"south": {
"jan": 0,
"feb": 0
}
}
A dictionary with “dimensions” (grid)
For a 2-D table, use tuples as keys:
rows, cols = 2, 3
grid = {(r, c): 0 for r in range(rows) for c in range(cols)} # a 2x3 "matrix"
grid[(1, 2)] = 5
print(grid)
print(len(grid), "cells")
Output:
{(0, 0): 0, (0, 1): 0, (0, 2): 0, (1, 0): 0, (1, 1): 0, (1, 2): 5}
6 cells
Start from a template (copy vs deepcopy)
import copy
template = {"name": "", "tags": []}
shallow = dict(template) # copies the top level only
shallow["tags"].append("new")
print("template after shallow copy:", template)
template = {"name": "", "tags": []}
deep = copy.deepcopy(template) # copies nested objects too
deep["tags"].append("new")
print("template after deepcopy: ", template)
Output:
template after shallow copy: {'name': '', 'tags': ['new']}
template after deepcopy: {'name': '', 'tags': []}
dict(template) and template.copy() only copy the outer dictionary, so nested lists are still shared. Use copy.deepcopy() for templates that contain lists or dicts.
Initialize an empty dictionary
{} and dict() both create an empty dictionary. {} is not an empty set; use set() for that:
print(type({}), type(set()), type({1, 2}))
Output:
<class 'dict'> <class 'set'> <class 'set'>
With a type hint (Python 3.9+):
inventory: dict[str, int] = {}
inventory["apples"] = 12
print(inventory, inventory.__class__.__name__)
Output:
{'apples': 12} dict
Details: create an empty dictionary in Python and check if a dictionary is empty.
Speed of each method
import timeit
for stmt in ["{}", "dict()", "{'a': 0, 'b': 0, 'c': 0}", "dict.fromkeys('abc', 0)", "{k: 0 for k in 'abc'}"]:
t = min(timeit.repeat(stmt, number=1_000_000, repeat=5))
print(f"{stmt:26} {t * 1000:6.0f} ns")
Output:
{} 15 ns
dict() 31 ns
{'a': 0, 'b': 0, 'c': 0} 52 ns
dict.fromkeys('abc', 0) 135 ns
{k: 0 for k in 'abc'} 104 ns
Times are nanoseconds per operation, from one run on a laptop. {} is faster than dict() because it is a literal rather than a function call, but all of these are fast enough for normal code.
Common mistake: a dictionary as a default argument
def add_score(name, scores={}): # the {} is created only once!
scores[name] = scores.get(name, 0) + 1
return scores
print(add_score("ann"))
print(add_score("bob")) # still contains ann
def add_score_fixed(name, scores=None):
if scores is None:
scores = {} # a new dict on every call
scores[name] = scores.get(name, 0) + 1
return scores
print(add_score_fixed("ann"))
print(add_score_fixed("bob"))
Output:
{'ann': 1}
{'ann': 1, 'bob': 1}
{'ann': 1}
{'bob': 1}
Default values are created once, when the function is defined, so every call shares that one dictionary. Use None as the default and create the dictionary inside the function.
Continue with these dictionary tutorials:
- Python dictionary comprehension
- Create an empty dictionary in Python
- Create a dictionary from two lists
- Python dictionary of lists
- Check if a Python dictionary is empty
Frequently asked questions
How do I initialize a dictionary with 0 in Python?
dict.fromkeys(keys, 0) or {k: 0 for k in keys}. For counting, collections.defaultdict(int) or Counter create the 0 automatically.
How do I initialize a dictionary with keys and values?
Write them directly ({"a": 1, "b": 2}), or combine two lists with dict(zip(keys, values)).
How do I initialize an empty dictionary?
d = {} or d = dict(). {} is a dictionary, not a set.
Why do all my keys change when I append to one list?
dict.fromkeys(keys, []) stores the same list under every key. Use {k: [] for k in keys} or defaultdict(list).
How do I initialize a dictionary with a default value for missing keys?
Use collections.defaultdict, for example defaultdict(int) (0), defaultdict(list) ([]) or defaultdict(lambda: "n/a"), or read with d.get(key, default).
Is a Python dictionary a hash map?
Yes. dict is Python’s built-in hash map: keys are hashed for fast lookups, and since Python 3.7 it also keeps insertion order.
Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn