Bootstrap demo

Python Dictionaries: Comprehensive Guide

A detailed reference for Python dictionary data structure with definitions and examples

Table of Contents

Introduction to Dictionaries

Definition: A dictionary in Python is an unordered, mutable collection of key-value pairs. Each key is unique and maps to a value, allowing efficient data retrieval. Dictionaries are implemented as hash tables, providing O(1) average time complexity for lookups.

Characteristics

  • Unordered (in Python versions < 3.7, ordered insertion is preserved in Python 3.7+)
  • Mutable (can be changed after creation)
  • Keys must be immutable (strings, numbers, tuples)
  • Values can be any data type

Creating Dictionaries

Using Curly Braces {}

# Empty dictionary
empty_dict = {}

# Dictionary with key-value pairs
student = {
    "name": "John Doe",
    "age": 21,
    "major": "Computer Science"
}

Using the dict() Constructor

# Using keyword arguments
student = dict(name="John Doe", age=21, major="Computer Science")

# Using a list of tuples
student = dict([("name", "John Doe"), ("age", 21), ("major", "Computer Science")])

# Using zip function
keys = ["name", "age", "major"]
values = ["John Doe", 21, "Computer Science"]
student = dict(zip(keys, values))

Accessing Dictionary Elements

Using Square Brackets []

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

print(student["name"])  # Output: John Doe
print(student["age"])   # Output: 21

# KeyError if key doesn't exist
# print(student["grade"])  # Raises KeyError

Using the get() Method

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

print(student.get("name"))        # Output: John Doe
print(student.get("grade"))       # Output: None
print(student.get("grade", "N/A")) # Output: N/A (default value)

Checking Key Existence

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

if "name" in student:
    print("Name exists in dictionary")

if "grade" not in student:
    print("Grade does not exist in dictionary")

Modifying Dictionaries

Adding/Updating Elements

student = {"name": "John Doe", "age": 21}

# Adding a new key-value pair
student["major"] = "Computer Science"

# Updating an existing value
student["age"] = 22

# Using update() method to add multiple items
student.update({"gpa": 3.8, "year": "Senior"})

print(student)
# Output: {'name': 'John Doe', 'age': 22, 'major': 'Computer Science', 'gpa': 3.8, 'year': 'Senior'}

Removing Elements

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

# Using del keyword
del student["age"]

# Using pop() method (returns the value)
major = student.pop("major")
print(major)  # Output: Computer Science

# Using popitem() method (removes and returns last inserted key-value pair)
item = student.popitem()
print(item)   # Output: ('name', 'John Doe')

# Clear all items
student.clear()
print(student)  # Output: {}

Dictionary Methods

Method Description Example
keys() Returns a view of all keys student.keys()
values() Returns a view of all values student.values()
items() Returns a view of all key-value pairs student.items()
get(key, default) Returns value for key, or default if not found student.get("age", 0)
pop(key, default) Removes key and returns value, or default if not found student.pop("age")
popitem() Removes and returns last inserted key-value pair student.popitem()
update(other_dict) Updates dictionary with key-value pairs from other student.update({"gpa": 3.8})
clear() Removes all items from dictionary student.clear()
copy() Returns a shallow copy of the dictionary new_student = student.copy()
setdefault(key, default) Returns value if key exists, else inserts key with default value student.setdefault("grade", "A")

Examples of Dictionary Methods

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

# keys(), values(), items()
print(list(student.keys()))    # Output: ['name', 'age', 'major']
print(list(student.values()))  # Output: ['John Doe', 21, 'Computer Science']
print(list(student.items()))   # Output: [('name', 'John Doe'), ('age', 21), ('major', 'Computer Science')]

# copy()
student_copy = student.copy()
student_copy["age"] = 22
print(student["age"])       # Output: 21 (original unchanged)
print(student_copy["age"])  # Output: 22

# setdefault()
grade = student.setdefault("grade", "A")
print(grade)  # Output: A (key was added with default value)
print(student)  # Now includes 'grade': 'A'

Dictionary Operations

Iterating Through Dictionaries

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

# Iterate through keys
for key in student:
    print(key, student[key])

# Iterate through key-value pairs
for key, value in student.items():
    print(f"{key}: {value}")

# Iterate through values only
for value in student.values():
    print(value)

Dictionary Length

student = {"name": "John Doe", "age": 21, "major": "Computer Science"}
print(len(student))  # Output: 3

Dictionary Membership Testing

student = {"name": "John Doe", "age": 21, "major": "Computer Science"}
print("name" in student)     # Output: True
print("grade" not in student) # Output: True

Dictionary Comprehensions

Dictionary comprehensions provide a concise way to create dictionaries.

# Create a dictionary of squares
numbers = [1, 2, 3, 4, 5]
squares = {x: x**2 for x in numbers}
print(squares)  # Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# Create a dictionary from two lists
keys = ['a', 'b', 'c']
values = [1, 2, 3]
mapping = {k: v for k, v in zip(keys, values)}
print(mapping)  # Output: {'a': 1, 'b': 2, 'c': 3}

# Filter items while creating a dictionary
numbers = [1, 2, 3, 4, 5]
even_squares = {x: x**2 for x in numbers if x % 2 == 0}
print(even_squares)  # Output: {2: 4, 4: 16}

Nested Dictionaries

Dictionaries can contain other dictionaries as values.

# Nested dictionary example
students = {
    "student1": {
        "name": "John Doe",
        "age": 21,
        "courses": ["Math", "Physics"]
    },
    "student2": {
        "name": "Jane Smith",
        "age": 22,
        "courses": ["Biology", "Chemistry"]
    }
}

# Accessing nested dictionary elements
print(students["student1"]["name"])          # Output: John Doe
print(students["student2"]["courses"][0])    # Output: Biology

# Modifying nested dictionary
students["student1"]["age"] = 22
students["student2"]["courses"].append("English")

# Adding a new nested dictionary
students["student3"] = {
    "name": "Bob Johnson",
    "age": 20,
    "courses": ["History", "Art"]
}

Common Use Cases

Counting Elements

# Count frequency of words in a text
text = "apple banana apple orange banana apple"
words = text.split()
word_count = {}

for word in words:
    word_count[word] = word_count.get(word, 0) + 1

print(word_count)  # Output: {'apple': 3, 'banana': 2, 'orange': 1}

Grouping Data

# Group people by age
people = [
    {"name": "John", "age": 25},
    {"name": "Jane", "age": 30},
    {"name": "Bob", "age": 25},
    {"name": "Alice", "age": 30}
]

grouped_by_age = {}
for person in people:
    age = person["age"]
    if age not in grouped_by_age:
        grouped_by_age[age] = []
    grouped_by_age[age].append(person["name"])

print(grouped_by_age)  # Output: {25: ['John', 'Bob'], 30: ['Jane', 'Alice']}

Configuration Settings

# Application configuration
config = {
    "database": {
        "host": "localhost",
        "port": 5432,
        "name": "myapp_db"
    },
    "server": {
        "host": "0.0.0.0",
        "port": 8000,
        "debug": True
    },
    "features": {
        "logging": True,
        "caching": False
    }
}

# Access configuration values
db_host = config["database"]["host"]
server_port = config["server"]["port"]

Best Practices

  1. Use descriptive keys: Choose meaningful key names that clearly indicate what data they hold.
  2. Handle missing keys appropriately: Use get() method or try-except blocks to handle missing keys instead of directly accessing with [].
  3. Use dictionary comprehensions: For creating dictionaries from iterables, use comprehensions for better readability and performance.
  4. Consider using defaultdict: For dictionaries that need default values for missing keys, consider using collections.defaultdict.
  5. Use items() for iteration: When you need both keys and values, use items() method for efficient iteration.
  6. Be cautious with mutable keys: Only use immutable types as dictionary keys.
from collections import defaultdict

# Using defaultdict for counting
word_count = defaultdict(int)
text = "apple banana apple orange banana apple"
words = text.split()

for word in words:
    word_count[word] += 1  # No need to check if key exists

print(dict(word_count))  # Output: {'apple': 3, 'banana': 2, 'orange': 1}

This comprehensive guide covers the essential aspects of Python dictionaries, from basic operations to advanced techniques. Dictionaries are a fundamental data structure in Python, and mastering them will significantly enhance your programming capabilities.