Python - Convert Two Lists to Dictionary

The most straightforward method combines `zip()` to pair elements from both lists with `dict()` to create the dictionary. This approach is clean, readable, and performs well for most scenarios.

Key Insights

  • Python offers multiple approaches to convert two lists into a dictionary, from basic zip() with dict() to dictionary comprehensions and the dict.fromkeys() method for specific use cases
  • The choice of method depends on list length handling requirements—whether you need strict length matching, want to handle mismatched lengths, or require default values for missing keys
  • Performance characteristics vary between methods, with zip() and dictionary comprehensions being most efficient for typical use cases, while manual iteration provides maximum control for complex transformations

Basic Conversion Using zip() and dict()

The most straightforward method combines zip() to pair elements from both lists with dict() to create the dictionary. This approach is clean, readable, and performs well for most scenarios.

keys = ['name', 'age', 'city', 'occupation']
values = ['Alice', 28, 'New York', 'Engineer']

result = dict(zip(keys, values))
print(result)
# Output: {'name': 'Alice', 'age': 28, 'city': 'New York', 'occupation': 'Engineer'}

The zip() function pairs corresponding elements from both lists, stopping when the shortest list is exhausted. This behavior prevents errors but silently truncates data if lists have different lengths.

keys = ['name', 'age', 'city', 'occupation', 'salary']
values = ['Bob', 32, 'Boston']

result = dict(zip(keys, values))
print(result)
# Output: {'name': 'Bob', 'age': 32, 'city': 'Boston'}
# Note: 'occupation' and 'salary' keys are missing

Dictionary Comprehension Method

Dictionary comprehensions provide a Pythonic alternative with additional flexibility for transformations during dictionary creation. This method is particularly useful when you need to apply functions or conditions.

keys = ['product', 'price', 'quantity']
values = ['Laptop', 999.99, 5]

result = {k: v for k, v in zip(keys, values)}
print(result)
# Output: {'product': 'Laptop', 'price': 999.99, 'quantity': 5}

You can incorporate transformations directly in the comprehension:

keys = ['name', 'email', 'phone']
values = ['JOHN DOE', 'JOHN@EMAIL.COM', '555-1234']

# Convert keys and values during dictionary creation
result = {k.lower(): v.title() if isinstance(v, str) else v 
          for k, v in zip(keys, values)}
print(result)
# Output: {'name': 'John Doe', 'email': 'John@Email.Com', 'phone': '555-1234'}

Add conditional logic to filter pairs:

keys = ['a', 'b', 'c', 'd', 'e']
values = [10, None, 30, None, 50]

# Exclude None values
result = {k: v for k, v in zip(keys, values) if v is not None}
print(result)
# Output: {'a': 10, 'c': 30, 'e': 50}

Handling Mismatched List Lengths

When lists have different lengths, you need explicit handling strategies. The itertools.zip_longest() function fills missing values with a specified default.

from itertools import zip_longest

keys = ['name', 'age', 'city', 'occupation']
values = ['Carol', 35]

result = dict(zip_longest(keys, values, fillvalue='N/A'))
print(result)
# Output: {'name': 'Carol', 'age': 35, 'city': 'N/A', 'occupation': 'N/A'}

For stricter validation, check lengths before conversion:

def lists_to_dict_strict(keys, values):
    if len(keys) != len(values):
        raise ValueError(f"Length mismatch: {len(keys)} keys vs {len(values)} values")
    return dict(zip(keys, values))

keys = ['x', 'y', 'z']
values = [1, 2]

try:
    result = lists_to_dict_strict(keys, values)
except ValueError as e:
    print(f"Error: {e}")
# Output: Error: Length mismatch: 3 keys vs 2 values

Using Enumerate for Index-Based Dictionaries

When you need indices as keys or want to create mappings based on position, enumerate() provides an elegant solution.

values = ['apple', 'banana', 'cherry', 'date']

# Use indices as keys
result = dict(enumerate(values))
print(result)
# Output: {0: 'apple', 1: 'banana', 2: 'cherry', 3: 'date'}

# Start enumeration from 1
result_from_one = dict(enumerate(values, start=1))
print(result_from_one)
# Output: {1: 'apple', 2: 'banana', 3: 'cherry', 4: 'date'}

Manual Iteration for Complex Logic

For complex transformations or when you need fine-grained control, manual iteration offers maximum flexibility.

keys = ['user_1', 'user_2', 'user_3']
values = [
    {'name': 'Alice', 'score': 95},
    {'name': 'Bob', 'score': 87},
    {'name': 'Carol', 'score': 92}
]

result = {}
for key, value in zip(keys, values):
    # Extract specific fields and compute derived values
    result[key] = {
        'name': value['name'],
        'score': value['score'],
        'grade': 'A' if value['score'] >= 90 else 'B'
    }

print(result)
# Output: {
#     'user_1': {'name': 'Alice', 'score': 95, 'grade': 'A'},
#     'user_2': {'name': 'Bob', 'score': 87, 'grade': 'B'},
#     'user_3': {'name': 'Carol', 'score': 92, 'grade': 'A'}
# }

Creating Dictionaries with Default Values

The dict.fromkeys() method creates a dictionary from a list of keys with a default value. This is useful when you have keys but need to initialize all values identically.

keys = ['cache_hit', 'cache_miss', 'timeout', 'error']
counters = dict.fromkeys(keys, 0)
print(counters)
# Output: {'cache_hit': 0, 'cache_miss': 0, 'timeout': 0, 'error': 0}

Warning: When using mutable default values, all keys reference the same object:

keys = ['user1', 'user2', 'user3']
# INCORRECT - all keys share the same list
wrong = dict.fromkeys(keys, [])
wrong['user1'].append('item')
print(wrong)
# Output: {'user1': ['item'], 'user2': ['item'], 'user3': ['item']}

# CORRECT - each key gets its own list
correct = {k: [] for k in keys}
correct['user1'].append('item')
print(correct)
# Output: {'user1': ['item'], 'user2': [], 'user3': []}

Performance Comparison

Different methods have varying performance characteristics depending on data size and complexity.

import timeit

keys = list(range(10000))
values = list(range(10000))

# Method 1: dict(zip())
time1 = timeit.timeit(lambda: dict(zip(keys, values)), number=1000)

# Method 2: Dictionary comprehension
time2 = timeit.timeit(lambda: {k: v for k, v in zip(keys, values)}, number=1000)

# Method 3: Manual loop
def manual_loop():
    result = {}
    for k, v in zip(keys, values):
        result[k] = v
    return result

time3 = timeit.timeit(manual_loop, number=1000)

print(f"dict(zip()): {time1:.4f}s")
print(f"Dict comprehension: {time2:.4f}s")
print(f"Manual loop: {time3:.4f}s")
# Typical output shows dict(zip()) as fastest, followed closely by comprehension

For most use cases, dict(zip()) provides the best balance of readability and performance. Use dictionary comprehensions when you need transformations, and reserve manual iteration for complex logic that doesn’t fit cleanly into comprehensions.

Handling Duplicate Keys

When the keys list contains duplicates, later values overwrite earlier ones. Handle this explicitly if needed:

keys = ['a', 'b', 'a', 'c', 'b']
values = [1, 2, 3, 4, 5]

# Standard behavior - last value wins
result = dict(zip(keys, values))
print(result)
# Output: {'a': 3, 'b': 5, 'c': 4}

# Collect all values for duplicate keys
from collections import defaultdict
multi_result = defaultdict(list)
for k, v in zip(keys, values):
    multi_result[k].append(v)
print(dict(multi_result))
# Output: {'a': [1, 3], 'b': [2, 5], 'c': [4]}

Choose your conversion method based on requirements: use dict(zip()) for simplicity, dictionary comprehensions for transformations, zip_longest() for handling length mismatches, and manual iteration for complex business logic.

Liked this? There's more.

Every week: one practical technique, explained simply, with code you can use immediately.