Key-Value Pairs in Python: Absolute Beginners Tutorial

Key-value pairs are the building blocks of Python dictionaries. Understanding them means you can store, look up, and update structured data without reaching for a database or a complicated data structure — just a plain Python dict.

Python's dict type is one of the language's most-used data structures. Under the hood it is a hash map, which means lookups are extremely fast regardless of how many entries the dictionary holds. Before you work with APIs, configuration files, JSON data, or database query results, you will encounter dictionaries — so grasping key-value pairs early pays dividends across every area of Python.

What Is a Key-Value Pair?

A key-value pair is exactly what it sounds like: a label (the key) paired with a piece of data (the value). Think of a physical address book where each name (key) maps to a phone number (value). You look up the name and get the number — you never need to scan every entry to find what you want.

In Python, the dictionary type is the native container for key-value pairs. A dictionary can hold any number of pairs, the values can be any Python object, and the keys must be immutable — meaning they cannot be changed after they are created.

Note

Valid key types include strings, integers, floats, and tuples containing only immutable elements. Lists and dictionaries cannot be used as keys because they are mutable and therefore unhashable.

The simplest way to picture the relationship is as a two-column table. The left column holds keys; the right column holds values. Every key is unique within a single dictionary. If you store two entries under the same key, Python keeps only the second one — no error, no warning.

Figure 1 — Anatomy of a Python key-value pair inside a dictionary literal. The key must be immutable; the value can be any Python object.

Creating a Dictionary

Python gives you two ways to create a dictionary. The first is a dictionary literal using curly braces. The second is the built-in dict() constructor. Both produce identical objects at runtime.

python
# Method 1 — dictionary literal
user = {
    "name": "Alice",
    "age": 30,
    "active": True
}

# Method 2 — dict() constructor
user = dict(name="Alice", age=30, active=True)

# Empty dictionary — add pairs later
config = {}
print(type(config))  # <class 'dict'>

Notice that the values in the example above are three different types: a string, an integer, and a boolean. Python imposes no restriction on what types values can be. You can even store a list, another dictionary, or a function as a value.

Pro Tip

When using the dict() constructor with keyword arguments, keys are automatically treated as strings, so you do not add quotation marks around them. This style reads cleanly for small dictionaries but cannot be used when your keys contain spaces or special characters.

Accessing values

You retrieve a value by placing its key inside square brackets. If the key does not exist, Python raises a KeyError. To avoid that, use the .get() method, which returns None by default or a value of your choosing.

python
user = {"name": "Alice", "age": 30}

# Square bracket access — raises KeyError if missing
print(user["name"])    # Alice

# .get() — returns None silently if key is missing
print(user.get("email"))          # None

# .get() with a default fallback value
print(user.get("email", "N/A"))   # N/A

In production code, .get() is usually safer than square bracket access whenever you cannot guarantee a key will be present — for example, when processing API responses or user-supplied data.

code builder click a token to place it

Build the statement that safely retrieves the "city" key from a dictionary called profile, returning "Unknown" if the key is missing:

your code will appear here...
"city" "Unknown" profile ["city"] .get( , ) None

Reading, Adding, and Removing Pairs

Once a dictionary exists, you will typically need to read its contents in bulk, add new pairs, update existing ones, or remove entries that are no longer needed. Python provides concise syntax and a set of built-in methods for each of these tasks.

Adding and updating pairs

Both operations use the same assignment syntax. Python checks whether the key already exists: if it does, the value is overwritten; if it does not, a new pair is created.

python
settings = {"theme": "dark", "font_size": 14}

# Add a new key-value pair
settings["language"] = "en"

# Update an existing value
settings["font_size"] = 16

print(settings)
# {'theme': 'dark', 'font_size': 16, 'language': 'en'}

Removing pairs

Two methods are available: del removes a pair and discards the value. .pop() removes a pair and returns the value, which is convenient when you need to process the data before deletion.

python
cart = {"apple": 3, "banana": 5, "cherry": 2}

# del — remove and discard
del cart["banana"]

# .pop() — remove and return the value
qty = cart.pop("cherry")
print(qty)     # 2
print(cart)    # {'apple': 3}

Iterating over a dictionary

The three dictionary iteration methods are .keys(), .values(), and .items(). The last one is the most common because it gives you both sides of each pair at once through tuple unpacking.

python
scores = {"Alice": 92, "Bob": 85, "Carol": 78}

# Iterate over keys only
for name in scores.keys():
    print(name)

# Iterate over values only
for score in scores.values():
    print(score)

# Iterate over key-value pairs together
for name, score in scores.items():
    print(f"{name} scored {score}")
Warning

Do not add or remove keys from a dictionary while iterating over it. Python will raise a RuntimeError: dictionary changed size during iteration. If you need to remove items based on a condition, iterate over a copy of the keys: for key in list(my_dict.keys()):

What it does
Returns the value for a key, or a default if the key is absent. Does not raise an error.
Example
d.get("email", "N/A") returns "N/A" if "email" is not in d.
What it does
Removes the key and returns its value. Raises KeyError if the key is missing and no default is provided.
Example
val = d.pop("age") removes "age" and stores the value in val.
What it does
Merges another dictionary (or iterable of key-value pairs) into the current one. Existing keys are overwritten; new keys are added.
Example
d.update({"role": "admin"}) adds or overwrites the "role" key in d.
What it does
Returns the value for a key if it exists. If the key is absent, it inserts the key with the given default and returns that default.
Example
d.setdefault("visits", 0) sets "visits" to 0 only if it is not already present.
What they do
Return live view objects — not static lists — of the dictionary's keys, values, or key-value pairs. Changes to the dictionary are reflected automatically.
Example
for k, v in d.items(): unpacks each pair into separate variables k and v.
spot the bug click the line that contains the bug

The function below is supposed to return the score for a given player. It contains one bug. Click the line you think is wrong, then hit check.

1 def get_score(scores, player):
2 if player in scores:
3 return scores[player][0]
4 return 0
The fix: change scores[player][0] to scores[player]. The values in this dictionary are plain integers, not sequences. Appending [0] attempts to subscript the integer, which raises a TypeError. Simply return the value directly with return scores[player].

How to Use Key-Value Pairs in Python

The five steps below cover the complete lifecycle of a key-value pair inside a Python dictionary: creation, reading, updating, deletion, and iteration. Work through each one in sequence and you will have a solid foundation for using dict objects in any real project.

  1. Create a dictionary with initial pairs

    Write a dictionary literal using curly braces: my_dict = {"key": value}. Separate each pair with a comma and use a colon between key and value. For an empty dictionary that you plan to populate later, use my_dict = {}.

  2. Access a value by its key

    Use my_dict["key"] for direct access when you know the key exists. Use my_dict.get("key", default) when the key might be absent — this avoids a KeyError and lets you supply a safe fallback.

  3. Add or update a key-value pair

    Assign a value with my_dict["key"] = value. If the key already exists, the value is replaced. If it does not, a new entry is appended. To merge an entire dictionary at once, use my_dict.update(other_dict).

  4. Remove a key-value pair

    Use del my_dict["key"] to remove a pair and discard the value. Use my_dict.pop("key") to remove the pair and capture the value in a variable for further use. Both raise KeyError if the key does not exist, so check with "key" in my_dict first when necessary.

  5. Iterate over key-value pairs

    Loop with for key, value in my_dict.items(): to work with both sides of each pair. Use my_dict.keys() when you only need keys, or my_dict.values() when you only need values. These methods return live view objects that reflect changes to the dictionary in real time.

"Dictionaries are Python's most versatile built-in data structure." — Python Documentation

Python Learning Summary Points

  1. A key-value pair links a unique, immutable key to a value of any type inside a Python dict. Keys must be hashable; values have no restrictions.
  2. Use square bracket access (d["key"]) when you know a key exists, and d.get("key", default) when the key might be absent to avoid KeyError exceptions.
  3. Adding, updating, and merging dictionaries all use simple assignment or the .update() method. Removing pairs uses del or .pop(), the latter returning the removed value.
  4. Iterating with .items() unpacks each pair into two variables, giving you clean, readable loops. Since Python 3.7, dictionaries guarantee insertion order, so iteration is predictable.
  5. Never modify a dictionary's size while looping over it. Iterate over a copy of the keys if you need to remove items during a loop.

Key-value pairs appear everywhere in Python — in JSON parsing, HTTP headers, environment variables, function keyword arguments, and database query results. The dict syntax you have practiced here applies directly to all of those contexts with no additional learning overhead.

check your understanding question 1 of 5

Frequently Asked Questions

A key-value pair in Python is a single entry in a dictionary where a unique key is associated with a corresponding value. The key acts as a label and the value holds the data. For example, in {"name": "Alice"}, "name" is the key and "Alice" is the value.

You create a dictionary using curly braces with colon-separated key-value pairs: my_dict = {"key": "value"}. You can also use the dict() constructor: my_dict = dict(key="value"). For an empty dictionary, use my_dict = {}.

Use square bracket notation: my_dict["key"]. To avoid a KeyError when the key may not exist, use my_dict.get("key"), which returns None by default, or my_dict.get("key", "fallback") to supply a custom default.

Use assignment: my_dict["new_key"] = "new_value". If the key already exists, its value is overwritten. If it does not exist, a new entry is created. To merge another dictionary, use my_dict.update(other).

Use del my_dict["key"] to remove a pair and discard the value, or my_dict.pop("key") to remove it and return the value. Both raise a KeyError if the key does not exist, so check with "key" in my_dict first when needed.

Use the .items() method: for key, value in my_dict.items():. This unpacks each entry into separate variables. Use .keys() for keys only, or .values() for values only.

Keys must be immutable (hashable) types. Strings, integers, floats, and tuples containing only immutable elements are all valid. Lists and other dictionaries cannot be used as keys because they are mutable.

Python keeps only the last assigned value for that key. No error is raised. For example, {"x": 1, "x": 2} produces {"x": 2}. Each key in a dictionary must be unique.

dict[key] raises a KeyError if the key does not exist. dict.get(key) returns None silently. You can supply a fallback with dict.get(key, default) to return a custom value instead of None.

Yes. Since Python 3.7, dictionaries maintain insertion order as part of the language specification. Items are returned in the order they were inserted when you iterate over a dictionary.