How to convert two lists into a dictionary in Python
Pair the lists with zip() and feed the pairs to dict(): dict(zip(keys, values)). Items are matched by position, so keys[0] maps to values[0].
zip() walks two lists side by side and yields (key, value) tuples; dict() accepts exactly that. The two things worth knowing before you ship it are what happens when the lists are different lengths (zip stops at the shorter one, silently) and what happens when a key repeats (the last value wins). Each example runs on this page — hit Run, then edit the code and run it again.
1dict(zip(keys, values))Recommended
This is the idiomatic one-liner. zip() is lazy and dict() consumes it directly, so there's no intermediate list to build — no imports, no loop.
Output
Prints {'name': 'CompileBytes', 'language': 'Python', 'stars': 42}. Dicts keep insertion order in Python 3.7+, so the result follows the order of keys. The keys list must hold hashable values — a list as a key raises TypeError: cannot use 'list' as a dict key.
2Uneven lengths and duplicate keys
zip() stops as soon as the shortest input runs out, so a mismatched pair of lists loses data without any warning. Since Python 3.10 you can pass strict=True to turn that into a ValueError instead — the safe default whenever the two lists are supposed to line up.
Output
The first line prints {'host': 8080, 'port': True} — debug is gone. With strict=True you get ValueError: zip() argument 2 is shorter than argument 1. And duplicate keys collapse: {'a': 3, 'b': 2}, so the dict can be shorter than the lists you started with.
3A dict comprehension
When you need to transform or filter while building — normalise the keys, cast the values, skip the blanks — wrap the same zip() in a comprehension. It's one pass, and it saves you from building the dict and then cleaning it up.
Output
The if v clause drops the empty Notes column, so both dicts have three keys, and stars comes out as '42' in the first and 42 — a real <class 'int'> — in the second. Plain dict(zip(...)) can't do either.
4itertools.zip_longest with a fillvalue
When the lists are legitimately uneven and you want to keep every key, zip_longest() pads the short side instead of truncating. The default fill is None; pass fillvalue for your own placeholder.
Output
debug survives, as None and then as 'unset'. One catch: this only reads well when the keys list is the longer one. If the values list is longer, the surplus pairs all take the fill value as their key and collapse into a single entry.
5Which should you use?
| Method | Uneven lengths | Can transform? | Best for |
|---|---|---|---|
| dict(zip(k, v)) | Truncates silently | No | Almost everything |
| dict(zip(k, v, strict=True)) | Raises ValueError | No | Lists that must line up (3.10+) |
| {k: v for k, v in zip(...)} | Truncates silently | Yes | Casting, renaming, filtering |
| dict(zip_longest(k, v, fillvalue=…)) | Pads the short side | No | Missing values you want to keep |
6Common variation: pairs and shared defaults
If your data already arrives as (key, value) pairs, skip zip() — dict() takes any iterable of pairs. And when every key should start with the same value, there's no second list at all: dict.fromkeys() does it in one call.
Output
Keep dict.fromkeys() to immutable defaults. The value is evaluated once and shared by every key, so dict.fromkeys(keys, []) gives all the keys the same list object — use a comprehension like {k: [] for k in keys} instead.
Frequently asked questions
What happens if the two lists have different lengths?
zip() stops at the shorter list and the extra items are dropped silently — dict(zip(["host", "port", "debug"], [8080, True])) returns {'host': 8080, 'port': True}. In Python 3.10+ pass strict=True to raise ValueError: zip() argument 2 is shorter than argument 1 instead, or use itertools.zip_longest() to pad the short side with a fillvalue.
What if the keys list contains duplicates?
It is not an error — dict keys are unique, so the last pair wins. dict(zip(["a", "b", "a"], [1, 2, 3])) returns {'a': 3, 'b': 2}, a dict with fewer entries than the input lists. If you need to keep every value, build a collections.defaultdict(list) and append instead.
Do the dictionary keys keep the order of the list?
Yes. Dicts preserve insertion order in Python 3.7+, and zip() walks the lists front to back, so the resulting dict follows the order of the keys list (minus any duplicates, which keep their first position but the last value).
How do I build the dictionary the other way round, values to keys?
Swap the arguments: dict(zip(values, keys)). The values then have to be hashable — a list or dict as a key raises TypeError: cannot use 'list' as a dict key. To invert a dict you already have, use {v: k for k, v in d.items()}.