Python dictionary internal working

Python Dictionary (with Examples)



Python dictionary internal working

What is a Python dictionary?

A Python dictionary is a built-in mapping type that stores values under keys. It’s implemented with an internal hash table that maps each hashable key to a memory location for its value. Dictionaries are the go-to structure for lookups and mappings in Python. We can think of them as fast “maps” or associative arrays.

  • Python dictionary is a mapping of key → value implemented as a hash table (fast lookups).
  • Keys must be unique and hashable (immutable types like str, int, tuple).
  • From Python 3.7+ insertion order of dict is guaranteed.
  • Typical dictionary operations (lookup, insert, delete) are O(1) average-time.

# Example: simple dictionary
person = {'name': 'Alice', 'age': 30, 
             'languages': ['Python', 'SQL']}
print(person)

Output:

{'name': 'Alice', 'age': 30, 'languages': ['Python', 'SQL']}

Python dictionary internal working

Creating a dictionary

You can create dictionaries using literal {}, the dict() constructor, from sequences of pairs, or using comprehensions. Use literal notation for readability; dict() is handy when converting from other mappings or sequences.


# Literal notation
d1 = {1: 'Python', 2: 'For', 3: 'Learn'}

# dict() constructor using keyword arguments
d2 = dict(a='Python', b='For', c='Learn')

# dict() from sequence of pairs
d3 = dict([(1, 'Python'), (2, 'For')])

# Empty dict
d4 = {}

print(d1)
print(d2)
print(d3)
print(d4)

Accessing items in Dictionary — [] vs .get()

Direct access d[key] raises KeyError if the key is missing. d.get(key, default) returns a default instead and is safer for optional keys.

d = {'name': 'Prajjwal', 1: 'Python', (1, 2): [1, 2, 4]}

# Direct access (KeyError if missing)
print(d['name'])

# Safe access using get()
print(d.get('name'))
print(d.get('missing', 'default-value'))
Prajjwal Prajjwal default-value

Adding & updating dictionary items

Assigning a value to d[key] inserts or updates. update() merges another mapping (or iterable of pairs) into the dict.

d = {1: 'Python', 2: 'For', 3: 'Python'}

# Add new key
d['age'] = 22

# Update existing key
d[1] = 'Python dict'

# Bulk update
d.update({'x': 100, 'y': 200})

print(d)
{1: 'Python dict', 2: 'For', 3: 'Python', 'age': 22, 'x': 100, 'y': 200}

Removing dictionary items

You can remove items with del, pop(key), popitem(), or clear entire dict with clear(). Note: since Python 3.7 popitem() removes the last-inserted key-value pair (LIFO), whereas older versions removed an arbitrary item.

d = {1: 'Python', 2: 'For', 3: 'Python', 'age': 22}

# del by key
del d['age']

# pop returns the value
val = d.pop(1)
print("popped value:", val)

# popitem returns and removes last-inserted pair (3.7+)
pair = d.popitem()
print("popitem:", pair)

# clear all
d.clear()
print("after clear:", d)
popped value: Python 
popitem: (3, 'Python') remaining: {2: 'For'} 
after clear: {}

Iteration – Loop over Dictionary – keys(), values(), items()

dict.keys(), dict.values(), and dict.items() produce view objects. Iterating for k, v in d.items() is the idiomatic way to access both key and value.

d = {'a': 1, 'b': 2, 'c': 3}

print(list(d.keys()))
print(list(d.values()))
print(list(d.items()))

for k, v in d.items():
   print(k, '->', v)

Output:

['a', 'b', 'c'] [1, 2, 3] [('a', 1), ('b', 2), ('c', 3)] a -> 1 b -> 2 c -> 3

Dictionary comprehension

Comprehensions let you build dictionaries compactly and readably — perfect for transforming lists or producing lookup tables (e.g., invert index or frequency mapping).

fruits = ['apple', 'banana', 'cherry']
index_map = {fruit: idx for idx, fruit in enumerate(fruits)}
even_squares = {n: n * n for n in range(10) if n % 2 == 0}

print(index_map)
print(even_squares)

Output:

index_map: {'apple': 0, 'banana': 1, 'cherry': 2} even_squares: {0: 0, 2: 4, 4: 16}

Nested dictionaries

Dictionaries often model JSON-style nested data. Access nested fields with chained indexing or safe patterns (get() with defaults). Use setdefault() or defaultdict patterns to create nested entries safely.

nested = {
'user1': {'name': 'Alice', 'roles': ['admin', 'user']},
'user2': {'name': 'Bob', 'roles': ['user']}
}

# Direct access
print(nested['user1']['name'])

# Safe access for missing keys
print(nested.get('user3', {}).get('name', 'Unknown'))

# Initialize nested safely
nested.setdefault('user3', {})['name'] = 'Charlie'
print(nested['user3'])

Output:

Alice Unknown {'name': 'Charlie'}

Merging dictionaries

Merge two dicts into a new dict using | (Python 3.9+) or {**a, **b} for older versions. update() mutates the left-hand dict.

a = {'x': 1, 'y': 2}
b = {'y': 20, 'z': 3}

# Python 3.9+: new merged dict
merged = a | b
print("merged:", merged)

# Unpacking merge (pre-3.9)
merged2 = {**a, **b}
print("merged2:", merged2)

# In-place
a.update(b)
print("a after update:", a)

Output:

merged: {'x': 1, 'y': 20, 'z': 3} merged2: {'x': 1, 'y': 20, 'z': 3} a_copy after update: {'x': 1, 'y': 20, 'z': 3}

Common helpers: defaultdict, Counter, OrderedDict

defaultdict simplifies grouping and nested initialization.
Counter solves counting/frequency problems.
OrderedDict is historically used to preserve order on older Python.
built-in dict preserves insertion order in modern Python.

from collections import defaultdict, Counter, OrderedDict

# defaultdict for grouping
groups = defaultdict(list)
groups['k'].append(1)
groups['k'].append(2)
print(dict(groups))

# Counter for frequency counting
cnt = Counter(['a', 'b', 'a', 'c', 'b', 'a'])
print(cnt)

# OrderedDict (historical use)
od = OrderedDict()
od['x'] = 1
od['y'] = 2
print(list(od.keys()))

Output:

defaultdict: {'k': [1, 2]} Counter: Counter({'a': 3, 'b': 2, 'c': 1}) OrderedDict keys: ['x', 'y']

Python Dict ↔ JSON

Dictionaries map directly to JSON objects. Use json.dumps() to serialize and json.loads() to parse. Remember booleans and null map to True/False/None.

import json

d = {'name': 'Alice', 'age': 30, 'active': True}
json_str = json.dumps(d)
print("json:", json_str)

d_back = json.loads(json_str)
print("dict:", d_back)

Performance & complexity

Dictionaries use hashing which gives average O(1) time for lookup, insert, and delete. In adversarial or degenerate cases (many hash collisions or extreme rehashing) costs degrade.

Example: many O(1) inserts and lookups (illustrative, not a benchmark)

d = {}
for i in range(100000):
d[i] = i * 2

print("lookup example:", d[50000])

Hashable keys Dictionary

-> Keys must be hashable (objects with an immutable hash value). Common mistakes:
-> Using mutable types (lists, dicts) as keys → TypeError.
-> Using floats with NaN — NaN != NaN, but hash behavior can be surprising.


# Hashable vs unhashable
valid = {(1, 2): 'pair', 'name': 'Alice', 10: 'ten'}
print(valid)

try:
bad = {[1, 2]: 'list-key'} # raises TypeError
except TypeError as e:
print("Error:", e)

Invert mapping (values may map to multiple keys)


m = {'a': 1, 'b': 2, 'c': 1}
inv = {}
for k, v in m.items():
inv.setdefault(v, []).append(k)
print("inverted:", inv)

Build index

fruits = ['apple', 'banana', 'cherry']
index_map = {i: v for i, v in enumerate(fruits)}
print(index_map)

Time and Space Complexity of Python Dictionary

Operation Average Complexity
Lookup O(1)
Insert / Update O(1)
Delete O(1)
Iterate O(n)
Space O(n)

Python Dictionary – Summary

Creation: {}, dict(), comprehensions
Access: d[key] (raises) vs d.get(key, default)
Update: d[key] = v, d.update(mapping)
Remove: del, pop, popitem, clear
Iteration: for k, v in d.items()
Tools: defaultdict, Counter, OrderedDict
JSON: json.dumps() / json.loads()
Performance: average O(1) operations, requires hashable keys.

FAQs — Python Dictionary

What is a Dictionary in Python?

A dictionary in Python is an unordered, mutable collection used to store data as key–value pairs. Keys must be unique and immutable (like strings, numbers, or tuples).

person = {"name": "Alice", "age": 25, "city": "London"}

How to create a Dictionary in Python?

You can create a dictionary using curly braces {} or the dict() constructor:

my_dict = {'a': 1, 'b': 2}
another_dict = dict(x=10, y=20)

How to access values in a Python Dictionary?

Use the key name inside square brackets or the get() method:

person = {"name": "Bob", "age": 30}
print(person["name"])
print(person.get("age"))

How to add or update values in a Python Dictionary?

Assign a value to a key directly. If the key exists, it updates the value; otherwise, it adds a new key-value pair:

person["age"] = 31
person["country"] = "UK"

How to remove items from a Python Dictionary?

Use pop(), del, or clear() to remove items:

person.pop("age")
del person["name"]
person.clear()

How to iterate through a Python Dictionary?

You can loop through keys, values, or both:

for key in person:
    print(key, person[key])

for k, v in person.items():
    print(k, v)

What are common methods available in Python Dictionary?
  • keys() – Returns all keys
  • values() – Returns all values
  • items() – Returns key-value pairs
  • get() – Retrieves value safely
  • pop() – Removes by key
  • update() – Merges another dictionary
  • clear() – Removes all items
How to merge two dictionaries in Python?

Use the update() method or the | merge operator (Python 3.9+):

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}

# Method 1
dict1.update(dict2)

# Method 2 (Python 3.9+)
merged = dict1 | dict2

How to check if a key exists in a Python Dictionary?

Use the in keyword:

if "name" in person:
    print("Key found!")

How to copy a Dictionary in Python?

Use copy() or the dict() constructor to create a shallow copy:

dict_copy = person.copy()
dict_clone = dict(person)

What is the difference between a Python List and a Dictionary?

A list stores values in an ordered sequence accessed by index, while a dictionary stores key–value pairs accessed by key.

my_list = [10, 20, 30]
my_dict = {"a": 10, "b": 20, "c": 30}

Can a Python Dictionary have duplicate keys?

No. Each key in a dictionary must be unique. If you use a duplicate key, the last assignment will overwrite the previous value.


Related Post