Python create dictionary
last modified October 30, 2026 Python 3.15
In this article we show how to create dictionaries in Python.
Python dictionary
A dictionary is a mutable collection of key/value pairs. Values are looked up by their keys, which must be unique within a dictionary and hashable; strings, numbers, and tuples of immutable values are typical keys. Values can be of any type.
Since Python 3.7, dictionaries keep the insertion order of their keys. When we print a dictionary or iterate over it, the pairs come out in the order in which they were added.
Empty dictionary
One way to create a dictionary is to start with an empty one and add pairs later.
capitals = {}
capitals['svk'] = 'Bratislava'
capitals['deu'] = 'Berlin'
capitals['dnk'] = 'Copenhagen'
print(capitals)
print(len(capitals))
items = dict()
items.update([('pens', 4), ('cups', 7)])
items.update(books=39)
print(items)
We create two dictionaries and fill them with data.
capitals = {}
capitals['svk'] = 'Bratislava'
Empty curly brackets create an empty dictionary. Assigning to a new key adds
a pair. (Note that {} is an empty dictionary, not an empty set;
an empty set is created with set().)
items = dict()
items.update([('pens', 4), ('cups', 7)])
items.update(books=39)
The dict constructor without arguments also creates an empty
dictionary. The update method adds pairs from another
dictionary, from an iterable of pairs, or from keyword arguments.
$ python empty.py
{'svk': 'Bratislava', 'deu': 'Berlin', 'dnk': 'Copenhagen'}
3
{'pens': 4, 'cups': 7, 'books': 39}
Dictionary literals
The most common way to create a dictionary is the literal notation. The pairs are written inside curly brackets and separated with commas; a key and its value are separated with a colon.
cities = {
'Bratislava': 475_000,
'Budapest': 1_686_000,
'Prague': 1_384_000,
'Warsaw': 1_863_000,
'Los Angeles': 3_820_000,
}
print(cities['Bratislava'])
print(cities)
points = {(0, 0): 'origin', (1, 0): 'east', (0, 1): 'north'}
print(points[(1, 0)])
dup = {'a': 1, 'b': 2, 'a': 3}
print(dup)
We create dictionaries with string and tuple keys.
cities = {
'Bratislava': 475_000,
...
}
A dictionary of cities and their approximate populations. Underscores in numeric literals make large numbers easier to read.
points = {(0, 0): 'origin', (1, 0): 'east', (0, 1): 'north'}
Tuples can be keys, which is useful for coordinates.
dup = {'a': 1, 'b': 2, 'a': 3}
A duplicate key is not an error: the last value wins, but the key keeps the position of its first occurrence.
$ python literals.py
475000
{'Bratislava': 475000, 'Budapest': 1686000, 'Prague': 1384000, 'Warsaw': 1863000, 'Los Angeles': 3820000}
east
{'a': 3, 'b': 2}
Keyword arguments
The dict constructor accepts keyword arguments, which become
string keys.
cities = dict(Bratislava=475_000, Budapest=1_686_000, Los_Angeles=3_820_000)
print(cities)
user = dict([('name', 'John Doe')], age=34, active=True)
print(user)
try:
eval("dict(Los Angeles=3_820_000)")
except SyntaxError as e:
print('SyntaxError:', e.msg)
This form avoids quoting the keys, but it has a limitation.
cities = dict(Bratislava=475_000, Budapest=1_686_000, Los_Angeles=3_820_000)
Keys must be valid Python identifiers. Los Angeles has to be written with an underscore; a space is a syntax error.
user = dict([('name', 'John Doe')], age=34, active=True)
Positional and keyword arguments can be combined.
$ python keyword_args.py
{'Bratislava': 475000, 'Budapest': 1686000, 'Los_Angeles': 3820000}
{'name': 'John Doe', 'age': 34, 'active': True}
SyntaxError: invalid syntax. Perhaps you forgot a comma?
From a sequence of pairs
Any iterable of two-element items can be passed to dict.
data = [('Bratislava', 475_000), ('Budapest', 1_686_000), ('Prague', 1_384_000)]
cities = dict(data)
print(cities)
text = 'host=localhost;port=8080;debug=on'
config = dict(item.split('=') for item in text.split(';'))
print(config)
try:
dict([('a', 1), ('b', 2, 3)])
except ValueError as e:
print(e)
We create dictionaries from a list of tuples and from parsed text.
text = 'host=localhost;port=8080;debug=on'
config = dict(item.split('=') for item in text.split(';'))
Each split('=') returns a two-element list, which is a valid
pair. The generator expression feeds the pairs to dict without
building an intermediate list.
try:
dict([('a', 1), ('b', 2, 3)])
except ValueError as e:
print(e)
An item with a different length raises a ValueError.
$ python from_pairs.py
{'Bratislava': 475000, 'Budapest': 1686000, 'Prague': 1384000}
{'host': 'localhost', 'port': '8080', 'debug': 'on'}
dictionary update sequence element #1 has length 3; 2 is required
Using zip
The zip function joins keys and values that are kept in two
separate sequences.
keys = ['coins', 'pens', 'books', 'cups']
vals = [13, 4, 39, 7]
items = dict(zip(keys, vals))
print(items)
print(dict(zip(keys, [1, 2])))
try:
dict(zip(keys, [1, 2], strict=True))
except ValueError as e:
print(e)
print(dict(enumerate(['zero', 'one', 'two'])))
We combine two lists into a dictionary.
print(dict(zip(keys, [1, 2])))
By default, zip stops at the end of the shorter input, so extra
keys are silently dropped.
dict(zip(keys, [1, 2], strict=True))
With strict=True, inputs of different length raise a
ValueError, which catches such mistakes early.
print(dict(enumerate(['zero', 'one', 'two'])))
The enumerate function produces index/value pairs, so it can
build a dictionary keyed by position.
$ python from_zip.py
{'coins': 13, 'pens': 4, 'books': 39, 'cups': 7}
{'coins': 1, 'pens': 2}
zip() argument 2 is shorter than argument 1
{0: 'zero', 1: 'one', 2: 'two'}
dict.fromkeys
The fromkeys class method creates a dictionary with keys from an
iterable and all values set to the same value, None by
default.
data = ['coins', 'pens', 'books', 'cups']
items = dict.fromkeys(data, 0)
print(items)
items['coins'] = 13
print(items)
print(dict.fromkeys('abc'))
groups = dict.fromkeys(['a', 'b'], [])
groups['a'].append(1)
print(groups)
groups = {k: [] for k in ['a', 'b']}
groups['a'].append(1)
print(groups)
words = ['sky', 'cloud', 'sky', 'rock', 'cloud']
print(list(dict.fromkeys(words)))
The example shows typical uses of fromkeys and one trap.
groups = dict.fromkeys(['a', 'b'], []) groups['a'].append(1)
All keys share the same list object. Appending through one key changes the value of every key.
groups = {k: [] for k in ['a', 'b']}
A comprehension evaluates [] for each key and creates separate
lists.
print(list(dict.fromkeys(words)))
Because keys are unique and keep their order, fromkeys is a
short way to remove duplicates from a list while preserving the order.
$ python fromkeys.py
{'coins': 0, 'pens': 0, 'books': 0, 'cups': 0}
{'coins': 13, 'pens': 0, 'books': 0, 'cups': 0}
{'a': None, 'b': None, 'c': None}
{'a': [1], 'b': [1]}
{'a': [1], 'b': []}
['sky', 'cloud', 'rock']
Dictionary comprehensions
A dictionary comprehension builds a dictionary from an iterable with an
expression of the form {key: value for item in iterable},
optionally with a filter.
capitals = {
'Bratislava': 475_503, 'Vilnius': 607_404, 'Lisbon': 545_796,
'Riga': 605_273, 'Warsaw': 1_863_056, 'Budapest': 1_686_222,
'Prague': 1_384_732, 'Helsinki': 684_018, 'Tokyo': 14_187_176,
}
small = {city: pop for city, pop in capitals.items() if pop < 1_000_000}
print(small)
squares = {n: n * n for n in range(1, 6)}
print(squares)
words = ['falcon', 'sky', 'cloud', 'owl']
lengths = {w: len(w) for w in words}
print(lengths)
codes = {'svk': 'Slovakia', 'cze': 'Czechia', 'hun': 'Hungary'}
inverted = {name: code for code, name in codes.items()}
print(inverted)
We create four dictionaries with comprehensions.
small = {city: pop for city, pop in capitals.items() if pop < 1_000_000}
The new dictionary contains only capitals with fewer than one million inhabitants.
inverted = {name: code for code, name in codes.items()}
Swapping keys and values inverts a dictionary. If several keys had the same value, only the last one would survive.
$ python comprehension.py
{'Bratislava': 475503, 'Vilnius': 607404, 'Lisbon': 545796, 'Riga': 605273, 'Helsinki': 684018}
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
{'falcon': 6, 'sky': 3, 'cloud': 5, 'owl': 3}
{'Slovakia': 'svk', 'Czechia': 'cze', 'Hungary': 'hun'}
Merging dictionaries
A new dictionary can be created by merging existing ones with the
** unpacking operator or the | operator.
defaults = {'host': 'localhost', 'port': 8080, 'debug': False}
user = {'port': 9000, 'debug': True}
print({**defaults, **user})
print(defaults | user)
print(user | defaults)
config = dict(defaults)
config |= {'debug': True}
print(config)
print({**defaults, 'port': 80, 'tls': True})
We merge user settings into default settings.
print({**defaults, **user})
print(defaults | user)
print(user | defaults)
For duplicate keys, the value from the right operand wins. The order of the operands therefore matters.
config = dict(defaults)
config |= {'debug': True}
The |= operator updates a dictionary in place. We update a copy
so that the defaults stay unchanged.
print({**defaults, 'port': 80, 'tls': True})
Unpacking can be mixed with literal pairs.
$ python merging.py
{'host': 'localhost', 'port': 9000, 'debug': True}
{'host': 'localhost', 'port': 9000, 'debug': True}
{'port': 8080, 'debug': False, 'host': 'localhost'}
{'host': 'localhost', 'port': 8080, 'debug': True}
{'host': 'localhost', 'port': 80, 'debug': False, 'tls': True}
Unpacking in comprehensions
Python 3.15 (PEP 798) allows ** unpacking directly in a
dictionary comprehension. It merges an arbitrary number of dictionaries.
layers = [
{'host': 'localhost', 'port': 8080},
{'port': 9000},
{'debug': True},
]
merged = {**layer for layer in layers}
print(merged)
stock = {'north': {'pens': 4}, 'south': {'cups': 7, 'books': 39}}
items = {**counts for counts in stock.values()}
print(items)
We merge a list of configuration layers and the values of a nested dictionary.
merged = {**layer for layer in layers}
Each dictionary is unpacked into the result in turn; later layers override earlier ones. Python 3.14 rejects this syntax. More examples are in Python unpacking in comprehensions.
$ python comprehension_unpack.py
{'host': 'localhost', 'port': 9000, 'debug': True}
{'pens': 4, 'cups': 7, 'books': 39}
$ python3.14 comprehension_unpack.py
File "/home/user/python/comprehension_unpack.py", line 7
merged = {**layer for layer in layers}
^^
SyntaxError: dict unpacking cannot be used in dict comprehension
Copying dictionaries
Assignment does not create a dictionary; it only creates another name for the same object. To create a new dictionary from an existing one, we copy it.
import copy
original = {'name': 'John', 'langs': ['Python', 'Go']}
alias = original
shallow = original.copy()
deep = copy.deepcopy(original)
original['name'] = 'Roger'
original['langs'].append('Rust')
print(alias)
print(shallow)
print(deep)
We change the original after making an alias, a shallow copy, and a deep copy.
shallow = original.copy() deep = copy.deepcopy(original)
The copy method (and dict(original)) creates a
shallow copy: a new dictionary that refers to the same values. The
deepcopy function copies the nested objects too.
The alias sees every change. The shallow copy keeps the old name, because the name was replaced in the original, but it shares the list, which was modified in place. The deep copy is completely independent.
$ python copying.py
{'name': 'Roger', 'langs': ['Python', 'Go', 'Rust']}
{'name': 'John', 'langs': ['Python', 'Go', 'Rust']}
{'name': 'John', 'langs': ['Python', 'Go']}
From JSON
JSON objects are parsed into Python dictionaries with
json.loads.
import json
text = '{"name": "John Doe", "age": 34, "langs": ["Python", "Go"], "admin": false}'
user = json.loads(text)
print(user)
print(type(user).__name__, user['langs'][0])
print(json.loads('{"1": "one", "2": "two"}'))
We parse a JSON document.
user = json.loads(text)
JSON objects become dictionaries, arrays become lists, and
false becomes False.
print(json.loads('{"1": "one", "2": "two"}'))
JSON keys are always strings; numeric keys are not converted back to integers.
$ python from_json.py
{'name': 'John Doe', 'age': 34, 'langs': ['Python', 'Go'], 'admin': False}
dict Python
{'1': 'one', '2': 'two'}
Keys must be hashable
A key's hash decides where the pair is stored, so keys must be hashable and must not change while in the dictionary.
grid = {(0, 0): 'start', (2, 3): 'goal'}
print(grid[(2, 3)])
for key in [['a', 'b'], {'x': 1}, {1, 2}]:
try:
{key: 'value'}
except TypeError as e:
print(e)
print({1: 'int', 1.0: 'float', True: 'bool'})
We try several types of keys.
for key in [['a', 'b'], {'x': 1}, {1, 2}]:
Lists, dictionaries, and sets are mutable and unhashable; using them as keys
raises a TypeError. A tuple or a frozenset can be
used instead.
print({1: 'int', 1.0: 'float', True: 'bool'})
The values 1, 1.0, and True are equal and have the same hash,
so they are the same key. The first key object is kept and the last value
wins.
$ python keys_hashable.py
goal
cannot use 'list' as a dict key (unhashable type: 'list')
cannot use 'dict' as a dict key (unhashable type: 'dict')
cannot use 'set' as a dict key (unhashable type: 'set')
{1: 'bool'}
frozendict
Python 3.15 (PEP 814) adds the frozendict built-in, an immutable
dictionary. It is created like a dict.
settings = frozendict(host='localhost', port=8080)
print(settings)
print(settings['port'])
try:
settings['port'] = 9000
except TypeError as e:
print(e)
updated = settings | {'port': 9000}
print(updated)
print(settings)
cache = {settings: 'local server'}
print(cache[frozendict(port=8080, host='localhost')])
print(isinstance(settings, dict))
We create a frozen dictionary of settings.
try:
settings['port'] = 9000
except TypeError as e:
print(e)
Item assignment is not supported.
updated = settings | {'port': 9000}
The | operator returns a new frozendict and leaves
the original unchanged.
cache = {settings: 'local server'}
print(cache[frozendict(port=8080, host='localhost')])
Unlike dict, a frozendict is hashable when its
values are, so it can be a dictionary key or a set member. Two frozen
dictionaries with the same pairs are equal regardless of their order.
A frozendict is not a subclass of dict.
$ python frozen.py
frozendict({'host': 'localhost', 'port': 8080})
8080
'frozendict' object does not support item assignment
frozendict({'host': 'localhost', 'port': 9000})
frozendict({'host': 'localhost', 'port': 8080})
local server
False
Source
In this article we have shown several ways to create dictionaries in Python.
Author
List all Python tutorials.