⚔️ Programming Challenge: Given an integer n
that could be very high (e.g., n=1000000
). How to initialize a Python dictionary of size n
that is fast, easy, and efficient?
Next, you’ll learn the five main ways to solve this and compare their performance at the end of this article. Interestingly, the winner Method 4 is 38% faster than the slowest Method 5 and 14% faster than the next fastest.
Scroll down to see the winning method that is both easy and maximally efficient! 🚀
Method 1: Basic For Loop
A simple and straightforward—but not super concise—way to create and initialize a dictionary of size n is to use a simple for
loop to fill up an initially empty dictionary by using dictionary assignments such as d[i] = None
in the loop body.
Here’s a simple code snippet using this approach:
def init_dict_1(n): ''' Initialize a dictionary with n key-value pairs. ''' d = {} for i in range(n): d[i] = None return d
The output:
print(init_dict_1(100)) {0: None, 1: None, 2: None, 3: None, 4: None, 5: None, 6: None, 7: None, 8: None, 9: None, 10: None, 11: None, 12: None, 13: None, 14: None, 15: None, 16: None, 17: None, 18: None, 19: None, 20: None, 21: None, 22: None, 23: None, 24: None, 25: None, 26: None, 27: None, 28: None, 29: None, 30: None, 31: None, 32: None, 33: None, 34: None, 35: None, 36: None, 37: None, 38: None, 39: None, 40: None, 41: None, 42: None, 43: None, 44: None, 45: None, 46: None, 47: None, 48: None, 49: None, 50: None, 51: None, 52: None, 53: None, 54: None, 55: None, 56: None, 57: None, 58: None, 59: None, 60: None, 61: None, 62: None, 63: None, 64: None, 65: None, 66: None, 67: None, 68: None, 69: None, 70: None, 71: None, 72: None, 73: None, 74: None, 75: None, 76: None, 77: None, 78: None, 79: None, 80: None, 81: None, 82: None, 83: None, 84: None, 85: None, 86: None, 87: None, 88: None, 89: None, 90: None, 91: None, 92: None, 93: None, 94: None, 95: None, 96: None, 97: None, 98: None, 99: None}
👉 Recommended Tutorial: Adding Elements to a Python Dictionary
Method 2: Dictionary Comprehension
Dictionary Comprehension is a concise and memory-efficient way to create and initialize dictionaries in one line of Python code. It consists of two parts: expression and context.
- The expression defines how to map keys to values.
- The context loops over an iterable using a single-line
for
loop and defines whichkey:value
pairs to include in the new dictionary.
Here’s how you can use dictionary comprehension to create and initialize a dictionary of size n
:
def init_dict_2(n): ''' Initialize a dictionary with n key-value pairs. ''' return {i:None for i in range(n)}
The output:
print(init_dict_2(100)) {0: None, 1: None, 2: None, 3: None, 4: None, 5: None, 6: None, 7: None, 8: None, 9: None, 10: None, 11: None, 12: None, 13: None, 14: None, 15: None, 16: None, 17: None, 18: None, 19: None, 20: None, 21: None, 22: None, 23: None, 24: None, 25: None, 26: None, 27: None, 28: None, 29: None, 30: None, 31: None, 32: None, 33: None, 34: None, 35: None, 36: None, 37: None, 38: None, 39: None, 40: None, 41: None, 42: None, 43: None, 44: None, 45: None, 46: None, 47: None, 48: None, 49: None, 50: None, 51: None, 52: None, 53: None, 54: None, 55: None, 56: None, 57: None, 58: None, 59: None, 60: None, 61: None, 62: None, 63: None, 64: None, 65: None, 66: None, 67: None, 68: None, 69: None, 70: None, 71: None, 72: None, 73: None, 74: None, 75: None, 76: None, 77: None, 78: None, 79: None, 80: None, 81: None, 82: None, 83: None, 84: None, 85: None, 86: None, 87: None, 88: None, 89: None, 90: None, 91: None, 92: None, 93: None, 94: None, 95: None, 96: None, 97: None, 98: None, 99: None}
👉 Recommended Tutorial: Python Dictionary Comprehension: A Powerful One-Liner Tutorial
Method 3: zip() and range()
The zip()
function takes an arbitrary number of iterables and aggregates them to a single iterable, a zip object. It combines the i-th values of each iterable argument into a tuple. Hence, if you pass two iterables, each tuple will contain two values.
You can use the zip()
function to construct a dictionary by first using it to create an iterable of tuples using zip(range(n), [None] * n)
where the first tuple values are the keys and the second tuple values are None
. Then pass the result into the dict()
function to create a dictionary out of it.
Here’s how this one-liner solution looks like:
def init_dict_3(n): ''' Initialize a dictionary with n key-value pairs. ''' return dict(zip(range(n), [None] * n))
The output:
print(init_dict_3(100)) {0: None, 1: None, 2: None, 3: None, 4: None, 5: None, 6: None, 7: None, 8: None, 9: None, 10: None, 11: None, 12: None, 13: None, 14: None, 15: None, 16: None, 17: None, 18: None, 19: None, 20: None, 21: None, 22: None, 23: None, 24: None, 25: None, 26: None, 27: None, 28: None, 29: None, 30: None, 31: None, 32: None, 33: None, 34: None, 35: None, 36: None, 37: None, 38: None, 39: None, 40: None, 41: None, 42: None, 43: None, 44: None, 45: None, 46: None, 47: None, 48: None, 49: None, 50: None, 51: None, 52: None, 53: None, 54: None, 55: None, 56: None, 57: None, 58: None, 59: None, 60: None, 61: None, 62: None, 63: None, 64: None, 65: None, 66: None, 67: None, 68: None, 69: None, 70: None, 71: None, 72: None, 73: None, 74: None, 75: None, 76: None, 77: None, 78: None, 79: None, 80: None, 81: None, 82: None, 83: None, 84: None, 85: None, 86: None, 87: None, 88: None, 89: None, 90: None, 91: None, 92: None, 93: None, 94: None, 95: None, 96: None, 97: None, 98: None, 99: None}
👉 Recommended Tutorial: Understanding the zip()
function in Python
Method 4: dict.fromkeys()
The method dict.fromkeys()
is a very useful method for creating new dictionaries from a given iterable of keys. It inputs keys and maybe an optional value, and outputs a dictionary with the specified keys, that are mapped either to optionally specified values or to the default None
value.
def init_dict_4(n): ''' Initialize a dictionary with n key-value pairs. ''' return dict.fromkeys(range(n))
The output:
print(init_dict_4(100)) {0: None, 1: None, 2: None, 3: None, 4: None, 5: None, 6: None, 7: None, 8: None, 9: None, 10: None, 11: None, 12: None, 13: None, 14: None, 15: None, 16: None, 17: None, 18: None, 19: None, 20: None, 21: None, 22: None, 23: None, 24: None, 25: None, 26: None, 27: None, 28: None, 29: None, 30: None, 31: None, 32: None, 33: None, 34: None, 35: None, 36: None, 37: None, 38: None, 39: None, 40: None, 41: None, 42: None, 43: None, 44: None, 45: None, 46: None, 47: None, 48: None, 49: None, 50: None, 51: None, 52: None, 53: None, 54: None, 55: None, 56: None, 57: None, 58: None, 59: None, 60: None, 61: None, 62: None, 63: None, 64: None, 65: None, 66: None, 67: None, 68: None, 69: None, 70: None, 71: None, 72: None, 73: None, 74: None, 75: None, 76: None, 77: None, 78: None, 79: None, 80: None, 81: None, 82: None, 83: None, 84: None, 85: None, 86: None, 87: None, 88: None, 89: None, 90: None, 91: None, 92: None, 93: None, 94: None, 95: None, 96: None, 97: None, 98: None, 99: None}
👉 Recommended Tutorial: Python’s Dictionary fromkeys()
Method
Method 5: Simple While Loop
You can also use a simple while loop to create a large dictionary one mapping at a time. The difference between a while
and a for
loop (see Method 1) is that you don’t rely on the range()
function this way which may take some time. The while loop approach works with simple integer addition operations.
Here’s the solution using while
:
def init_dict_5(n): ''' Initialize a dictionary with n key-value pairs. ''' d = dict() i = 0 while i<n: d[i] = None i += 1 return d
The output:
print(init_dict_5(100)) {0: None, 1: None, 2: None, 3: None, 4: None, 5: None, 6: None, 7: None, 8: None, 9: None, 10: None, 11: None, 12: None, 13: None, 14: None, 15: None, 16: None, 17: None, 18: None, 19: None, 20: None, 21: None, 22: None, 23: None, 24: None, 25: None, 26: None, 27: None, 28: None, 29: None, 30: None, 31: None, 32: None, 33: None, 34: None, 35: None, 36: None, 37: None, 38: None, 39: None, 40: None, 41: None, 42: None, 43: None, 44: None, 45: None, 46: None, 47: None, 48: None, 49: None, 50: None, 51: None, 52: None, 53: None, 54: None, 55: None, 56: None, 57: None, 58: None, 59: None, 60: None, 61: None, 62: None, 63: None, 64: None, 65: None, 66: None, 67: None, 68: None, 69: None, 70: None, 71: None, 72: None, 73: None, 74: None, 75: None, 76: None, 77: None, 78: None, 79: None, 80: None, 81: None, 82: None, 83: None, 84: None, 85: None, 86: None, 87: None, 88: None, 89: None, 90: None, 91: None, 92: None, 93: None, 94: None, 95: None, 96: None, 97: None, 98: None, 99: None}
👉 Recommended Tutorial: Understanding Python Loops from the Ground Up
Performance Evaluation
We used an Intel Core i7 with 1.8GHz TurboBost up to 4.6 GHz with 8GB DDR4 Memory and 512GB storage (not that it mattered) to compare each of the five methods on various values of n—using an exponentially increasing function as shown in the code below.
This allowed us to stress-test the dictionary creation functions discussed in this article on large inputs to generate dictionaries with up to 100 million (!) entries. 😮

⚡ Experiment Results: The output shows that Method 4 is the fastest and scaled best, followed by Method 2, Method 3, Method 1, and finally Method 5 (the slowest). The winner Method 4 is 38% faster than the slowest Method 5 and 14% faster than the next fastest.
- Method 1 needed 0.69 seconds for 100 million dict entries.
- Method 2 needed 0.67 seconds for 100 million dict entries.
- Method 3 needed 0.69 seconds for 100 million dict entries.
- Method 4 needed 0.58 seconds for 100 million dict entries.
- Method 5 needed 0.93 seconds for 100 million dict entries.
We used the following code to generate this graphic:
import time import matplotlib.pyplot as plt def init_dict_1(n): ''' Initialize a dictionary with n key-value pairs. ''' d = {} for i in range(n): d[i] = None return d def init_dict_2(n): ''' Initialize a dictionary with n key-value pairs. ''' return {i:None for i in range(n)} def init_dict_3(n): ''' Initialize a dictionary with n key-value pairs. ''' return dict(zip(range(n), [None] * n)) def init_dict_4(n): ''' Initialize a dictionary with n key-value pairs. ''' return dict.fromkeys(range(n)) def init_dict_5(n): ''' Initialize a dictionary with n key-value pairs. ''' d = dict() i = 0 while i<n: d[i] = None i += 1 return d # Performance Evaluation xs = [] y_1, y_2, y_3, y_4, y_5 = [], [], [], [], [] for x in [10**i for i in range(3, 8)]: xs.append(x) # Method 1 Elapsed Runtime: start = time.time() init_dict_1(x) stop = time.time() y_1.append(stop - start) # Method 2 Elapsed Runtime: start = time.time() init_dict_2(x) stop = time.time() y_2.append(stop - start) # Method 3 Elapsed Runtime: start = time.time() init_dict_3(x) stop = time.time() y_3.append(stop - start) # Method 4 Elapsed Runtime: start = time.time() init_dict_4(x) stop = time.time() y_4.append(stop - start) # Method 5 Elapsed Runtime: start = time.time() init_dict_5(x) stop = time.time() y_5.append(stop - start) print(y_1) print(y_2) print(y_3) print(y_4) print(y_5) plt.plot(xs, y_1, '.-', label='Method 1') plt.plot(xs, y_2, 'o-', label='Method 2') plt.plot(xs, y_3, 'x-', label='Method 3') plt.plot(xs, y_4, 'v--', label='Method 4') plt.plot(xs, y_5, '.--', label='Method 5') plt.xscale('log') plt.legend() plt.grid() plt.show()
In case you need the exact values in seconds, here’s the output, one line per Method:
[0.0, 0.0, 0.008193492889404297, 0.07302451133728027, 0.6917409896850586] [0.0, 0.0009975433349609375, 0.006968975067138672, 0.07086825370788574, 0.6777770519256592] [0.0, 0.0, 0.008328437805175781, 0.07159566879272461, 0.6925091743469238] [0.000997304916381836, 0.0, 0.006980180740356445, 0.06289315223693848, 0.5841073989868164] [0.0, 0.0009970664978027344, 0.009291648864746094, 0.09641242027282715, 0.9321954250335693]
You can see that for the largest n=100000000
, we obtain a runtime of 0.93 seconds for Method 5 and only 0.58s for Method 4.
Summary
The easiest and fastest way to create and initialize a dictionary with n elements is dict.fromkeys(range(n))
that maps each integer i
to the default value None
. If you need another default value (such as 42
), just pass it as a second argument into the function.

While working as a researcher in distributed systems, Dr. Christian Mayer found his love for teaching computer science students.
To help students reach higher levels of Python success, he founded the programming education website Finxter.com that has taught exponential skills to millions of coders worldwide. He’s the author of the best-selling programming books Python One-Liners (NoStarch 2020), The Art of Clean Code (NoStarch 2022), and The Book of Dash (NoStarch 2022). Chris also coauthored the Coffee Break Python series of self-published books. He’s a computer science enthusiast, freelancer, and owner of one of the top 10 largest Python blogs worldwide.
His passions are writing, reading, and coding. But his greatest passion is to serve aspiring coders through Finxter and help them to boost their skills. You can join his free email academy here.