Related: Software engineering | 8-22-2025 Sets | 8-14-2025 Tuples | ![]
Dictionary
Dictionary
A dictionary in Python is a data structure that allows you to associate hashable keys to values. In other programming languages it is known as an associative array, hash map, or hash table.
Hash value
A hash value is an integer that is used to compare dictionary keys during look up.
Hashable
In Python, an object is hashable if it has a hash value which does not change during its lifetime (immutable). Hashable objects which compare equal must have the same hash value.
Hashable data types
''' immutable data types these can be used as dictionary keys.'''
`str`, `int`, `float`, `bool`, `tuple`.
Non hashable data types
''' mutable date types these can't be used as dictionary kesy '''
`list`, `dict`, `set`
Keys
Keys must be hashable and unique across the dictionary. They cannot contain mutable data structures such as lists, dicts, or sets. As of Python 3.7, dict key order is guaranteed to be the order in which entries are inserted.
Values
Values can be of any data type or structure. They can also also nest freely, so they can contain data types like lists, dicts or sets
Dictionary time complexity
Given a key, dictionaries can retrieve values in O(1) time complexity(constant). Compared to searching a list or array this is much faster but it uses significantly more memory. Dictionaries are especially useful in scenarios where the collection of items is large and must be accessed and updated frequently like caching data or counting word occurrences in a large document.
Dictionary construction
'''passing a list of key,value tuples.'''
wombat = dict([("name","Wombat"),("speed",23),("land_animal",True)])
print(wombat)
''' Using key=value arguments.'''
bear = dict(name="Black Bear", speed=40, land_animal=True)
print(bear)
''' create an empty dictionary '''
my_dict = {}
''' using the dict() constructor '''
my_dict1 = dict()
import json
print(json.dumps(my_dict, indent=2))
Updating dictionary values
You can change an entry value by assigning a new value to the key.
bear = dict(name="Black Bear", speed=40, land_animal=True)
whale = {"name": "Blue Whale", "speed": 35, "land_animal": False}
bear["name"] = "Grizzly Bear"
whale["speed"] = 25
print(bear)
print(whale)
Adding new key: value pairs
New key: value pairs can be added to a dictionary using square bracket notation.
bear["color"] = "tawney"
whale["blowholes"] = 1
print(bear,whale)
Removing(pop-ing) dictionary entries.
You can use the .pop(<key>, <default value>) method to remove a key:value pair from the dictionary and return the value for use like get(), .pop(<key>) accepts a second argument (dict.pop(<key>, <default value>)) that will be returned if the key is not found. This prevents a KeyError being raised.
bear = dict(name="Black Bear", speed=40, land_animal=True)
print(f"Original dictionary: {bear}") # Create the dictionary
removed_value = bear.pop("name")
print(f"The value returned by pop: '{removed_value}'")
print(f"Dictionary after pop: {bear}")
print("-" * 20) # Use .pop() successfully. This removes the key and returns the value
try:
bear.pop("name")
except KeyError:
print("As expected, a KeyError was raised because the 'name' key is already gone.")
print("-" * 20) # trying to pop "name" again will cause an error.
default_pop_value = bear.pop("name", "Unknown")
print(f"Value from popping a missing key with a default: '{default_pop_value}'")
print(f"The dictionary is unchanged: {bear}") # with a default argument to prevent the error
Nested dictionaries
A dictionary can contain dictionaries this is called a nested dictionary
myfamily = {"child1": {"name": "Emil", "year": 2004}} # dictionary containing a dictionary
print(myfamily)
if you want to add three dictionaries into a new dictionary:
child1 = {"name": "Emil", "year": 2004}
child2 = {"name": "Tobias", "year": 2007}
child3 = {"name": "Linus", "year": 2011}# create three dictionaries, then create one dictionary that will contain the other three dictionaries:
myfamily = {"child1": child1, "child2": child2, "child3": child3}
print(myfamily)
Access items in nested dictionaries
print(myfamily["child2"]["name"])
Loop through nested dictionaries
You can loop through the keys and value of all nested dictionaries by using the items() method.
child1 = {"name": "Emil", "year": 2004}
child2 = {"name": "Tobias", "year": 2007}
child3 = {"name": "Linus", "year": 2011}
myfamily = {"child1": child1, "child2": child2, "child3": child3} # Sample data for the dictionary
for x, y in myfamily.items():
print(x) # Outer loop: 'x' gets the main dictionary's key (e.g., "child1"). 'y' gets the value, which is the inner dictionary (e.g., {"name": "Emil", "year": 2004}).
for z in y:
print(z + ": " + str(y[z]))# Inner loop iterates through the current 'y' dictionary: 'z' gets the inner dictionary's key (e.g., "name", "year").y[z] accesses the value for that inner key (e.g., y["name"] is "Emil").
Dictionary methods
id: M-UNYlMMfX3Irj0-ZPvZc
===
`clear()`
`copy()`
`fromkeys()`
`get()`
`items()`
`keys()`
`pop()`
`popitem()`
`setdefault()`
`update()`
`values()`
`dict.get(key, default)`
===
Removes all the elements from the dictionary
Returns a copy of the dictionary
Returns a dictionary with the specified keys and value
Returns the value of the specified key
Returns a list containing a tuple for each key value pair
Returns a list containing the dictionary's keys
Removes the element with the specified key
Removes the last inserted key-value pair
Returns the value. If it doesn't exist: insert the specified value
Updates the dictionary with the specified key-value pairs
Returns a list of all the values in the dictionary
Look up a key; if it’s missing, return `default`.
Inventory management system
An implementation of an inventory management system using python dictionaries.
items = ["coal", "wood", "wood", "diamond", "diamond", "diamond"]
def create_inventory(items):
inventory = {} # create a new dict
for item in items: # loop through list of items
inventory[item] = inventory.get(item, 0) + 1 # populate dict, default 0 for count.
return inventory
def add_items(inventory, items):
for i in (items): # loop through list of items you want to add
inventory[i] = inventory.get(i,0)+1 # creates a new key:(default 0) or inc key count.
return inventory
def decrement_items(inventory, items):
for item in items: # loop through list of items you want to decrease
if inventory.get(item,0) >0: # check if it's in the inventory
inventory[item] = inventory.get(item)-1 # if it is dec count by 1
return inventory
def remove_item(inventory, item):
if item in inventory: # check if item is in inv
inventory.pop(item) # remove it from the inv
return inventory
def list_inventory(inventory):
list = []
for x,y in inventory.items(): # loop through list of Key:val tuples
if y > 0: # if val > 0 append the key:val as a tuple to the list
list.append((x,y))
return list
my_inventory = create_inventory(items)
print(my_inventory)
my_inventory = add_items(my_inventory ,["iron","wood","copper","iron"])
print(my_inventory)
my_inventory = decrement_items(my_inventory ,["iron"])
print(my_inventory)
my_invetory = remove_item(my_inventory ,"copper")
print(my_inventory)
my_inventory = list_inventory(my_inventory)
print(my_inventory)
Inserting dictionary values
You can use setdefault() for error free insertion. setdefault(key, <default value>) will return the value if the key is found in the dictionary. If the key is not found, it will insert the (key, default value) pair and return the default value for use.
palette = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}
palette.setdefault("Rock Bronwn",'#694605')
print(palette)
Populating a dictionary from an Iterable
You can quickly populate a dictionary from an iterable using the dict.fromkeys(iterable, default value) method. The value will be the default value you set.
tuple = ( 'Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink', 'fill in hex color here')
new_dict = dict.fromkeys(tuple,1)
print (new_dict)
Iterating over entries in a Dictionary via views
The dict.items(), dict.keys(), and dict.values() methods return iterable views of a dictionary that can be easily looped over without altering them. Views are also dynamic -- when underlying dictionary data changes, the associated view object will reflect the change.
palette1 = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}
print(palette1.keys(),"\n") # list of keys
print(palette1.values(),"\n") # list of values
print(palette1.items(),"\n") # list of key:value pairs
palette1 ['Purple Mountains Majesty'] = (128, 118, 163)
print("Update: ['Purple Mountains Majesty'] = (128, 118, 163)","\n")
print(palette1.keys(),"\n") # list of keys
print(palette1.values(),"\n") # list of values
print(palette1.items()) # list of key:value pairs
Iterating over entries in a Dictionary via views cont:
Views are also reversible. This allows keys, values, or (key, value) pairs to be iterated over in Last-in, First-out (LIFO) order by using reversed(<dict>.keys()), reversed(<dict>.values()), or reversed(<dict>.items()):
palette2 = {'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple baseline': '#161748'}
for item in palette2.items(): # Iterating in insertion order (First in, first out)
print(item)
for item in reversed(palette2.items()): # Iterating in the reverse direction. (Last in, first out)
print ("Reversed item:",item)
Sorting dictionaries
Dictionaries don’t have a built in sorting method however you can sort a dict using the sorted() with dict.items(). The sorted view can then be used to create a new dictionary. Like iteration, the default sort is over the dictionary keys.
color_palette = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple baseline': '#161748'}
sorted_palette = dict(sorted(color_palette.items()))
reversed_sorted_palette = dict(sorted(color_palette.items(), reverse =True))
print("Unsorted:", color_palette,"\n")
print("Sorted:", sorted_palette, "\n")
print("Sorted and Reversed: ", reversed_sorted_palette, "\n")
Combining dictionaries
<dict_one>.update(<dict_two>) can be used to combine two dictionaries. This method will take the (key, value) pairs of <dict_two> and write them into <dict_one>.Where keys in the two dictionaries overlap, the value in dict_one will be overwritten by the corresponding value from dict_two:
palette3 = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}
palette4 = {'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple Baseline': '#161748'}
print("Palette3: ", palette3,"\n")
print("Palette4: ", palette4,"\n")
palette3.update(palette4)
print("Updated Palette3: ", palette3,"\n")
Merge or update dictionaries via the union (|) operators
Python 3.9 introduced a different way of merging dicts: the union operators dict1 | dict2 will return a new dict with the merged keys and values of dict1 and dict2. When both dictionaries share keys, dict_two values take precedence.
palette5 = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}
palette6 = {'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple baseline': '#161748'}
combined_palette = palette5 | palette6
print("Palette5: ", palette5,"\n")
print("Palette6: ", palette6,"\n")
print("Combined palette: ", combined_palette, "\n")
Merge or update dictionaries with an iterable.
There are two ways to do this dict_one |= other and <dict_one>.update(<other>) other can be either a dict or an iterable of (key, value) pairs:
palette7 = {'Grassy Green': (155, 196, 0), 'Purple Mountains Majesty': (128, 118, 163), 'Misty Mountain Pink': (249, 197, 189)}
new_dict |= palette7
print(new_dict)
new_dict2 = {}
new_dict2.update(palette7)
print(new_dict2)
Implementing a shopping cart system using python dictionaries
def add_item(current_cart, items_to_add):
for item in items_to_add: # loop through the items you want to add
current_cart[item] = current_cart.get(item,0)+1 # insert them into the car with default value of 0
return current_cart
def read_notes(notes):
cart = {} # create a cart
for items in notes: # loop through the users notes
cart[items] = cart.get(items,0)+1 # update the cart with items from note with a default value of 0
return cart
def update_recipes(ideas, recipe_updates):
updated_ideas = ideas # store current ideas in new dict
updated_ideas.update(recipe_updates) # update the new dict with the recipe_updates
return updated_ideas
def sort_entries(cart):
return dict(sorted(cart.items()))
def send_to_store(cart, aisle_mapping):
fulfillment_cart = {}
for item,quantity in cart.items(): # loop through the items and their quantity
fulfillment_cart[item] = [quantity] + aisle_mapping[item] # for each items set its value to a list with its quantity and aisle info
return dict(sorted(fulfillment_cart.items(), reverse =True))
def update_store_inventory(fulfillment_cart, store_inventory):
for item,quantity in fulfillment_cart.items(): # loop through the users cart
store_inventory[item][0] -= quantity[0] # accesss that item in the store using its index in the cart iterable
if store_inventory[item][0] < 1: # check if the count is less than 1
store_inventory[item][0] = 'Out of Stock'
return store_inventory
print("--- Testing add_item ---")
cart1 = {'milk': 1, 'bread': 2}
items1 = ['eggs', 'milk', 'cheese']
print(f"Initial cart: {cart1}, Items to add: {items1}")
updated_cart1 = add_item(cart1, items1)
print(f"Updated cart: {updated_cart1}\n")
print("--- Testing read_notes ---")
notes1 = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
print(f"Notes: {notes1}")
read_cart1 = read_notes(notes1)
print(f"Cart from notes: {read_cart1}\n")
print("--- Testing update_recipes ---")
ideas1 = {'cake': 'flour, sugar', 'cookies': 'butter, sugar'}
updates1 = {'cake': 'flour, sugar, eggs', 'bread': 'flour, water'}
print(f"Initial ideas: {ideas1}, Updates: {updates1}")
updated_ideas1 = update_recipes(ideas1, updates1)
print(f"Updated ideas: {updated_ideas1}\n")
print("--- Testing sort_entries ---")
unsorted_cart = {'banana': 2, 'apple': 1, 'orange': 3, 'milk': 1}
print(f"Unsorted cart: {unsorted_cart}")
sorted_cart = sort_entries(unsorted_cart)
print(f"Sorted cart: {sorted_cart}\n")
print("--- Testing send_to_store ---")
cart_for_store = {'apple': 2, 'banana': 1, 'milk': 3}
aisle_map = {'apple': ['Aisle 1'], 'banana': ['Aisle 2'], 'milk': ['Aisle 3'], 'orange': ['Aisle 4']}
print(f"Cart for store: {cart_for_store}, Aisle mapping: {aisle_map}")
fulfillment_cart = send_to_store(cart_for_store, aisle_map)
print(f"Fulfillment cart: {fulfillment_cart}\n")
print("--- Testing update_store_inventory ---")
store_inventory = {'apple': [5, 'Aisle 1'], 'banana': [3, 'Aisle 2'], 'milk': [1, 'Aisle 3'], 'orange': [10, 'Aisle 4']}
print(f"Initial store inventory: {store_inventory}")
print(f"Fulfillment cart for update: {fulfillment_cart}")
updated_inventory = update_store_inventory(fulfillment_cart, store_inventory)
print(f"Updated store inventory: {updated_inventory}\n")