Skip to main content

Python Dictionaries: Key-Value Pairs & Access Methods

Dictionaries are Python's most powerful data structure for storing related data. Unlike lists that use numeric indexes, dictionaries use keys to map to values, making them ideal for real-world data like user profiles, configurations, and lookups. A dictionary is an unordered, mutable collection where each key is unique and must be immutable (string, number, or tuple), while values can be any type.

What Are Python Dictionaries and Key-Value Pairs?

A dictionary stores data as key-value pairs—think of a real dictionary where a word (key) maps to its definition (value). Python dictionaries are mutable (modifiable after creation), maintain insertion order since Python 3.7, and cannot have duplicate keys. If you assign a new value to an existing key, the old value is overwritten.

Key-value pairs are the fundamental unit of a dictionary. Each key must be unique and immutable; each value can be any Python object. This structure is more flexible and efficient than lists when you need to retrieve data by a descriptive identifier rather than a numeric position.

# A real-world dictionary example
student = {
"name": "Alice",
"age": 21,
"major": "Computer Science",
"gpa": 3.85
}
# "name" is a key; "Alice" is its value
# Each key uniquely identifies a piece of data

How to Create Dictionaries in Python

Python offers two primary methods to create dictionaries: curly-brace literal syntax and the dict() constructor. The curly-brace method is more readable for small, pre-known dictionaries; the dict() constructor is useful for dynamic creation and converting other data structures.

Creating Dictionaries with Curly Braces

The most common syntax uses curly braces {} with key: value pairs separated by commas. An empty dictionary is represented as {}.

# Empty dictionary
empty_dict = {}

# Dictionary with string keys and mixed value types
student = {
"name": "Alice",
"age": 21,
"major": "Computer Science",
"enrolled": True
}

# Dictionary with integer keys
scores = {
1: 95,
2: 87,
3: 92
}

# Keys and values can be of different types within the same dictionary
mixed = {
"title": "My Book",
42: "The Answer",
3.14: "Pi"
}

The key comes first, followed by a colon, then the value. Pairs are separated by commas. Python 3.7+ preserves insertion order, so iterating over a dictionary returns items in the order they were added.

Creating Dictionaries with the dict() Constructor

The dict() constructor is a built-in function that creates dictionaries from keyword arguments or iterables of key-value pairs.

# From keyword arguments (keys become strings automatically)
person = dict(name="Bob", age=30, city="New York")
print(person)
# Output: {'name': 'Bob', 'age': 30, 'city': 'New York'}

# From a list of tuples (each tuple is a key-value pair)
employee_data = [
("id", 101),
("department", "Engineering"),
("salary", 95000)
]
employee = dict(employee_data)
print(employee)
# Output: {'id': 101, 'department': 'Engineering', 'salary': 95000}

# Combining both methods
config = dict(debug=True, timeout=30, **{"version": "1.0"})
print(config)
# Output: {'debug': True, 'timeout': 30, 'version': '1.0'}

The dict() constructor is particularly useful when converting lists of tuples or merging dictionaries (using the ** unpacking operator).

Accessing Dictionary Values

Dictionary access is one of the most frequent operations. Python provides two main methods: direct bracket access and the safer .get() method. Choosing the right method prevents crashes when keys don't exist.

Direct Access with Square Brackets

The bracket syntax dictionary[key] retrieves the value associated with a key immediately. If the key exists, the value is returned; if not, a KeyError is raised.

student = {
"name": "Alice",
"age": 21,
"major": "Computer Science"
}

# Direct access
name = student["name"]
print(f"Name: {name}")
# Output: Name: Alice

# Accessing a non-existent key causes an error
try:
gpa = student["gpa"]
except KeyError:
print("The 'gpa' key does not exist in the dictionary")

Direct bracket access is fast and suitable when you are certain the key exists. Use it when accessing mandatory fields or when you deliberately want an error if data is missing.

Safe Access with the .get() Method

The .get() method returns the value for a key if it exists; otherwise, it returns None (or a default value you specify). It never raises KeyError, making it ideal for optional data.

student = {
"name": "Alice",
"age": 21,
"major": "Computer Science"
}

# Safe access with .get()
name = student.get("name")
print(f"Name: {name}")
# Output: Name: Alice

# Access a non-existent key—returns None
gpa = student.get("gpa")
print(f"GPA: {gpa}")
# Output: GPA: None

# Provide a default value if key is missing
gpa_default = student.get("gpa", "Not available")
print(f"GPA: {gpa_default}")
# Output: GPA: Not available

# Default can be any value, including zero or empty string
semester = student.get("semester", 0)
print(f"Semester: {semester}")
# Output: Semester: 0

The .get() method accepts an optional second argument specifying the default value. This is the standard, safer approach in production code.

Checking for Key Existence

Before accessing a dictionary, you can verify whether a key exists using the in operator. This is useful for conditional logic.

student = {
"name": "Alice",
"age": 21,
"major": "Computer Science"
}

# Check if key exists
if "gpa" in student:
print(student["gpa"])
else:
print("GPA not recorded")
# Output: GPA not recorded

# Check if key does NOT exist
if "email" not in student:
print("Email not in record")
# Output: Email not in record

The in operator returns a boolean and is often used to guard bracket access, combining certainty with directness.

Building a User Profile Application

Here is a complete, practical example that demonstrates dictionary creation, access, and real-world use:

# Create a user profile dictionary
user_profile = {
"username": "alice_dev",
"email": "[email protected]",
"followers": 1500,
"is_active": True,
"account_type": "premium",
"join_date": "2022-03-15"
}

# Display profile using safe .get() access
print("--- User Profile ---")
print(f"Username: {user_profile.get('username')}")
print(f"Email: {user_profile.get('email')}")
print(f"Followers: {user_profile.get('followers')}")
print(f"Account Type: {user_profile.get('account_type', 'free')}")

# Optionally retrieve fields that may not exist
location = user_profile.get('location', 'Unknown')
print(f"Location: {location}")

# Check membership status
if user_profile.get('is_active'):
print("Account is active")
else:
print("Account is inactive")

print("--------------------")

This example demonstrates both safe data retrieval with .get() and conditional logic based on dictionary contents.

Dictionary vs. Lists: When to Use Each

Dictionaries are superior to lists when data has meaningful labels (names, IDs, roles). Lists are better for ordered sequences. Dictionaries scale well for sparse data (many optional fields).

# Lists: ordered, numeric index
grades = [95, 87, 92, 88] # Access by position

# Dictionaries: keyed access, descriptive labels
student_info = {
"math": 95,
"english": 87,
"science": 92,
"history": 88
} # Access by subject name

# Dictionary is clearer: student_info["math"] vs. grades[0]

Key Takeaways

  • Dictionaries store data as key-value pairs with unordered, mutable collections where each key is unique and immutable.
  • Create dictionaries using curly-brace syntax ({key: value}) or the dict() constructor; the dict() constructor is useful for keyword arguments or converting iterables.
  • Access dictionary values directly with brackets (dictionary[key]) when certain the key exists, or safely with .get(key, default) to avoid KeyError.
  • Use the in operator to check whether a key exists before accessing it.
  • Since Python 3.7, dictionaries maintain insertion order, so iteration returns items in the order they were added.
  • Dictionaries are ideal for real-world data like user profiles, configurations, and lookup tables where semantic labels are more useful than numeric indexes.

Frequently Asked Questions

What is the difference between dictionary access with [] and .get()?

Direct bracket access (dict[key]) raises KeyError if the key doesn't exist; .get(key) returns None (or a default value) safely. Use brackets when the key must exist; use .get() for optional fields.

Can dictionary keys be numbers or tuples?

Yes. Keys must be immutable types: strings, integers, floats, tuples, or booleans. Lists and dictionaries cannot be keys because they are mutable. Numbers as keys are valid but less descriptive than string keys.

What happens if I assign a value to an existing key?

The old value is overwritten. Dictionaries cannot have duplicate keys; assigning to an existing key replaces its value. For example, dict["name"] = "Bob" overwrites the previous value for the "name" key.

How do I check if a dictionary is empty?

Use if not dictionary: or if len(dictionary) == 0:. An empty dictionary is falsy in a boolean context, so if not my_dict: is the Pythonic way to check.

What is the difference between a dictionary and a JSON object?

A dictionary is a Python data structure; JSON is a text format. You can convert Python dictionaries to JSON using json.dumps() and parse JSON into dictionaries using json.loads(). The structure is similar but JSON is language-agnostic.

Further Reading