Python — Dictionaries

A dictionary connects related information as key-value pairs. Keys must be unique; values can be any type. Dictionaries keep insertion order (Python 3.7+).

Defining and Accessing

alien = {'color': 'green', 'points': 5}
 
print(alien['color'])            # 'green' — KeyError if key missing
color = alien.get('color')       # 'green' — None if key missing
speed = alien.get('speed', 0)    # 0 — custom default if key missing

Adding and Modifying

alien['x_position'] = 0          # add new key-value pair
alien['color'] = 'yellow'        # modify existing value

Removing

del alien['points']              # permanently removes key and its value

Length

num_responses = len(fav_languages)

Looping

# All key-value pairs — most common
for name, language in fav_languages.items():
    print(f"{name}: {language}")
 
# Keys only
for name in fav_languages.keys():
    print(name)
 
# Values only
for language in fav_languages.values():
    print(language)
 
# Keys in reverse sorted order
for name in sorted(fav_languages.keys(), reverse=True):
    print(name)

.items() unpacks into two variables

for k, v in d.items() is the idiomatic way to iterate key-value pairs. .keys() is the default iteration (you can just say for k in d:), but explicit .keys() is clearer.

Nesting

List of dictionaries

users = []
new_user = {'last': 'fermi', 'first': 'enrico', 'username': 'efermi'}
users.append(new_user)

Lists inside a dictionary

fav_languages = {
    'jen': ['python', 'ruby'],
    'phil': ['python', 'haskell'],
}
for name, langs in fav_languages.items():
    for lang in langs:
        print(f"  - {lang}")

Dictionary of dictionaries

users = {
    'aeinstein': {'first': 'albert', 'last': 'einstein', 'location': 'princeton'},
    'mcurie':    {'first': 'marie',  'last': 'curie',    'location': 'paris'},
}
for username, user_dict in users.items():
    full_name = f"{user_dict['first']} {user_dict['last']}"
    location  = user_dict['location']
    print(f"\nUsername: {username}")
    print(f"\tFull name: {full_name.title()}")
    print(f"\tLocation: {location.title()}")

Nesting depth warning

Nesting more than two levels usually signals a better structure is needed — consider a class when nesting gets complex.

Dictionary Comprehensions

# Loop approach
squares = {}
for x in range(5):
    squares[x] = x**2
 
# Comprehension — same result
squares = {x: x**2 for x in range(5)}
 
# zip() pairs two lists into a dict
group_1 = ['kai', 'abe', 'ada', 'gus', 'zoe']
group_2 = ['jen', 'eva', 'dan', 'isa', 'meg']
pairings = {name: name_2 for name, name_2 in zip(group_1, group_2)}

Cross-References

  • PythonLists — lists and dicts are the two primary Python data structures
  • PythonControlFlow — for loops over dict items/keys/values
  • PythonOOP — when nesting gets deep, a class is usually the cleaner answer
graph TD
    A[Dictionary] --> B["Access: dict[key] or .get(key, default)"]
    A --> C["Add/Modify: dict[key] = value"]
    A --> D["Remove: del dict[key]"]
    A --> E["Loop: .items() / .keys() / .values()"]
    A --> F[Nesting]
    F --> G[List of dicts]
    F --> H[Lists in a dict]
    F --> I[Dict of dicts]
    A --> J["{k:v for k,v in iter} — comprehension"]