Python Dictionaries Explained with Real World Examples
A practical beginner guide to Python dictionaries. Learn the key-value mental model, the most useful methods, and the patterns that show up in real-world programs.
A Python dictionary is the data structure you reach for the moment a position number stops being a meaningful name for an item. This guide is Python dictionaries explained with the help of real world examples, so the abstract idea of key-value storage shows up in shapes you will actually meet. Lists are great when the order matters and the items are interchangeable, but a real program quickly grows things like user records, configuration settings, counts of words, and lookup tables. All of those examples share one shape, which is a label paired with a value, and that is exactly what a dictionary is built for.
The Key-Value Mental Model
Picture a dictionary as a small filing cabinet. Each drawer has a label on the front, and inside each drawer is a single value. To put something away you write the label first, then drop in the value. To get it back you ask the cabinet for the drawer with that label. The labels are called keys, and the contents are called values. Keys are unique inside one cabinet, so writing to an existing label simply replaces what was inside before.
The catch is that the labels need to be stable, which in Python means they need to be hashable. Strings, numbers, and tuples of hashable items all qualify, but lists do not, because lists can change after the fact and that would break the cabinet's ability to find anything. If the difference between mutable and immutable feels fuzzy, our guide on Python tuples vs lists and when to use each draws the line cleanly and explains why hashability is the dividing rule.
Creating, Reading, and Updating Entries
The simplest way to make a dictionary is to write key-value pairs between curly braces. You can also start empty and grow the cabinet a drawer at a time. Reading a value back is a matter of using square brackets with the key, just like a list, except the bracket holds a label rather than a position. Updating is the same syntax as reading, just on the left side of an equals sign.
user = {"name": "ada", "age": 36, "city": "berlin"}
user["age"] = 37
user["job"] = "engineer"
print(user["name"])Each line above is doing one specific thing. The first creates a dictionary with three entries. The second replaces the value at an existing key. The third adds a brand new entry, because the key did not exist before. The print line reads the value back out. Notice how the syntax for replace and add is identical, which is part of what makes dictionaries feel natural once the model is in place.
Safe Lookups Without Crashes
The biggest beginner trap with dictionaries is asking for a key that does not exist. Square bracket lookup is strict and raises a KeyError when the label is missing, which is sometimes what you want and sometimes a fast way to crash a program. The get method is the gentle alternative. It returns None if the key is missing, or any default value you pass as the second argument.
config = {"host": "localhost", "port": 8080}
timeout = config.get("timeout", 30)The timeout variable ends up as 30 because the key was missing and the default kicked in. That pattern is enormously useful when a program reads settings from a file and wants to tolerate missing values gracefully. The setdefault method goes one step further by also writing the default back into the dictionary, which is handy when you are building up counts or grouping values under a key for the first time.
Iterating Over a Dictionary
Looping over a dictionary is one of the friendliest parts of the language. The default loop walks the keys, which is the most common case. Pair that with the items method when you want both the key and the value in the same step, and you get a clean two-name unpacking that reads almost like English. The values method walks just the values when the keys are not interesting.
prices = {"apple": 1.2, "bread": 2.5, "milk": 1.8}
for item, cost in prices.items():
print(f"{item} costs {cost}")A loop like that is a regular shape in real programs because so many data sources arrive as label-value pairs. Lines from a CSV file, parameters parsed from a URL, fields returned by a database row, counts produced from a frequency analysis. Whenever you find yourself walking pairs, the dictionary is doing most of the work for you. If you want a more compact way to build a dictionary in one expression, our guide on Python dictionary comprehensions explained with examples shows the comprehension shape and pairs it with the longer loop it replaces.
Real-World Patterns
The first pattern beginners meet is counting. You read through a sequence of words, and for each word you bump a counter inside a dictionary. The setdefault method or the standard library's Counter class makes that pattern almost a one-liner. The second pattern is grouping. You take a list of records and route each one into a sub-list keyed by some field, like grouping employees by department. The dictionary holds the lists, and the keys are the department names.
A third pattern is the lookup table. Instead of a chain of if statements that compares the same variable against many possible values, you build a dictionary where the keys are the possible values and the values are the responses. The whole chain shrinks down to a single dictionary access, and adding a new case is a one-line edit. That refactor often makes a program feel suddenly tidier without changing what it does. If you want a sturdier mental footing on the broader collection landscape before going further, our guide on Python data types explained with real examples gives the wider tour.
Nested Dictionaries
Real data rarely fits in a single flat dictionary. A user record might have an address, which is itself a small dictionary of street and city and country. A configuration file might have sections, each holding their own settings. Python lets you nest dictionaries inside dictionaries with no special syntax, just the same key-value pairs at every level. Reading deep into a nested structure is a chain of bracket lookups.
The trade-off with nesting is that every level of depth is another place for a missing key to bite you. The get method helps because you can chain it with another default that is itself a dictionary, and keep the lookup chain safe all the way down. When the nesting gets four or five layers deep, it is usually a signal that a class or a dataclass would describe the shape more clearly. For most beginner programs, two levels of nesting is plenty.
Rune AI
Key Insights
- A dictionary maps unique hashable keys to values, like a small labelled filing cabinet.
- Bracket lookup raises KeyError on a missing key; use get with a default to handle that gracefully.
- The items method gives a clean way to loop over both keys and values in one pass.
- Counting, grouping, and lookup tables are the three patterns that justify reaching for a dictionary by default.
Frequently Asked Questions
What can be used as a dictionary key in Python?
When should I use get instead of square brackets on a dictionary?
Are Python dictionaries ordered now?
Conclusion
A dictionary is the right tool whenever an item is best identified by a label rather than a position. The key-value mental model maps cleanly onto user records, configuration, lookup tables, and counts. Once the basic methods are in muscle memory, dictionaries stop feeling like a separate feature and start feeling like a natural extension of the language. Most real Python programs would not be readable without them. A good follow-up exercise is to take a small program you wrote with parallel lists, one for names and one for scores, and rewrite it with a single dictionary that pairs each name to its score. The program shrinks, and the chance of the two lists drifting out of sync goes to zero. That is the quiet superpower of choosing the right collection.
More in this topic
Python Dictionary Comprehensions Explained with Examples
A practical beginner guide to Python dictionary comprehensions. Learn the syntax, the filter clause, the inversion pattern, and when to reach for a regular loop instead.
Python List Comprehensions Explained Step by Step
A step by step beginner guide to Python list comprehensions. Learn the shape, the filter clause, the nested form, and when to reach for a regular loop instead.
Python *args and **kwargs Explained the Easy Way
A clear beginner guide to Python *args and **kwargs. Learn what the stars do, how to use both in function signatures, and the patterns that make flexible functions readable.