Plenty of tutorials still initialize a Python dictionary with keys and values by filling an empty {} in an index loop, or use dict.fromkeys(keys, []), which shares one list.
There’s a cleaner route. If your keys and values sit in two lists, dict(zip(keys, values)) builds the dictionary in one line.
Below, I’ll show you four ways and the two traps I see most. I ran every snippet on Python 3.12.5.
The sample keys and values we’ll use
Every example uses two lists: four store names as keys and their Q3 sales as values.
stores = ["Austin", "Denver", "Boise", "Tampa"]
sales = [12500.50, 9800.25, 0.00, 8750.40] # Q3 2026
- Boise opened in September, so its value is 0.00
- The lists pair up by position: third key, third value
For empty and nested dictionaries, see how to initialize a dictionary in Python.
Method 1: Initialize a dictionary from keys and values with zip() (Recommended)
I use this one most. zip() pairs the lists; dict() makes them a dictionary.
Here’s the code:
stores = ["Austin", "Denver", "Boise", "Tampa"]
sales = [12500.50, 9800.25, 0.00, 8750.40] # Q3 2026
q3 = dict(zip(stores, sales))
print(q3)
print(dict(zip(stores, sales[:3]))) # Tampa vanishes
try:
dict(zip(stores, sales[:3], strict=True))
except ValueError as err:
print("ValueError:", err)
Output:
{'Austin': 12500.5, 'Denver': 9800.25, 'Boise': 0.0, 'Tampa': 8750.4}
{'Austin': 12500.5, 'Denver': 9800.25, 'Boise': 0.0}
ValueError: zip() argument 2 is shorter than argument 1
All four stores land in the dictionary, Boise included.

How does this code work?
zip(stores, sales) yields pairs like ("Austin", 12500.5). dict() reads each pair as key and value.
So here’s the catch: zip() stops at the shorter list, so Tampa is silently dropped.
strict=True (Python 3.10+) raises a ValueError instead. More options are in creating a dictionary from two lists.
Pro Tip: Already have pairs, like CSV rows? Pass the list of tuples straight to dict().
Method 2: Build the dictionary with a dict comprehension
Use a comprehension when you compute values or skip keys. Each store gets a 10% target, minus Boise.
stores = ["Austin", "Denver", "Boise", "Tampa"]
sales = [12500.50, 9800.25, 0.00, 8750.40] # Q3 2026
targets = {s: round(v * 1.1, 2) for s, v in zip(stores, sales) if v}
print(targets)
orders = {s: [] for s in stores} # a new list per store
orders["Austin"].append("A-1001")
print(orders)
Output:
{'Austin': 13750.55, 'Denver': 10780.28, 'Tampa': 9625.44}
{'Austin': ['A-1001'], 'Denver': [], 'Boise': [], 'Tampa': []}

How does this code work?
Each pair unpacks into s, v. if v skips Boise’s 0.0, and the rounded target becomes the value.
[] runs once per store, so no list is shared. More in Python dictionary comprehension.
Method 3: Initialize every key with the same value using dict.fromkeys()
If you need one shared default, like a zero counter, dict.fromkeys(keys, value) is shortest.
stores = ["Austin", "Denver", "Boise", "Tampa"]
sales = [12500.50, 9800.25, 0.00, 8750.40] # Q3 2026
visits = dict.fromkeys(stores, 0)
visits["Denver"] += 3
print(visits)
orders = dict.fromkeys(stores, []) # one shared list
orders["Austin"].append("A-1001")
print(orders)
Output:
{'Austin': 0, 'Denver': 3, 'Boise': 0, 'Tampa': 0}
{'Austin': ['A-1001'], 'Denver': ['A-1001'], 'Boise': ['A-1001'], 'Tampa': ['A-1001']}

How does this code work?
+= 3 gives Denver a new number, so counters work. See incrementing a dictionary value.
Why does dict.fromkeys(keys, []) share one list?
fromkeys() stores one default object under every key. Numbers can’t change in place, so you’re safe there.
A list can, so every store shows A-1001. Use {s: [] for s in stores} instead, or see a dictionary of lists in Python.
Method 4: Fill an empty dictionary in a for loop
The older pattern still works when each value needs extra logic.
stores = ["Austin", "Denver", "Boise", "Tampa"]
sales = [12500.50, 9800.25, 0.00, 8750.40] # Q3 2026
q3 = {}
for i in range(len(stores)):
q3[stores[i]] = sales[i]
print(q3 == dict(zip(stores, sales)))
Output:
True

How does this code work?
Each pass of range(len(stores)) adds one pair. Empty dicts: {} creating an empty Python dictionary.
The catch: if your sales list is shorter, you get an IndexError.
Picking the right way to initialize a dictionary
| Method | Use it when you have |
|---|---|
dict(zip(keys, values)) | Two lists |
| Dict comprehension | Computed values or skipped keys |
dict.fromkeys(keys, 0) | One shared immutable default |
Empty {} + loop | Multi-step logic per value |
Things to Keep in Mind When Initializing Dictionaries
zip()silently drops extra keys; addstrict=Trueif you need matching lengths.fromkeys(keys, [])shares one list; use a comprehension ordefaultdict(list).- Keys must be hashable; lists can’t be keys.
Working with dictionaries this week? Try these next:
- Store multiple values per key in Python
- Convert a tuple to a dictionary in Python
- Add items to a Python dictionary
- Check if a Python dictionary is empty
Frequently asked questions
How do I initialize a dictionary with keys and values in Python?
Use dict(zip(keys, values)) when you have two lists.
How do I initialize a dictionary with keys and a default value?
Use dict.fromkeys(keys, 0).
Why do all my keys change when I append to one list?
You used dict.fromkeys(keys, []), which shares one list. Use a comprehension.
What happens if the keys and values lists have different lengths?
zip() stops at the shorter one unless you pass strict=True.
Is a dict comprehension faster than a for loop?
Usually, and it’s shorter.
Where is dict.fromkeys() documented?
See dict.fromkeys() in the Python docs.

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