Python Dictionaries: A Complete Guide

Python dictionaries are one of the most powerful and flexible data structures in the language. Known for their key-value pair structure, dictionaries offer fast lookups, dynamic resizing, and a wide range of methods for manipulation. Whether you’re storing configuration data, mapping relationships, or managing complex datasets, dictionaries are a go-to tool in Python programming. In this comprehensive guide, we’ll explore everything you need to know about Python dictionaries—how to create them, their methods, operations, and practical use cases. This guide is designed for beginners and experienced developers alike, providing a deep dive into the world of dictionaries.

Let’s get started!


What Are Dictionaries in Python?

link to this section

A dictionary in Python is an unordered, mutable collection of key-value pairs enclosed in curly braces ({}). Each key is unique and maps to a specific value, making dictionaries ideal for associative data storage. Keys must be immutable (e.g., strings, numbers, tuples), while values can be of any type—numbers, strings, lists, or even other dictionaries.

Here’s a simple example:

my_dict = {"name": "Alice", "age": 25, "city": "New York"}
print(my_dict) # Output: {'name': 'Alice', 'age': 25, 'city': 'New York'}

Dictionaries are optimized for quick retrieval of values based on their keys, leveraging a hash table under the hood.


Creating Dictionaries in Python

link to this section

There are several ways to create a dictionary:

  1. Using Curly Braces :
    person = {"name": "Bob", "age": 30}
    print(person) # Output: {'name': 'Bob', 'age': 30}
  2. Using the dict() Constructor :
    person = dict(name="Charlie", age=28)
    print(person) # Output: {'name': 'Charlie', 'age': 28}
  3. From a List of Tuples :
    pairs = [("name", "Diana"), ("age", 22)] 
    person = dict(pairs)
    print(person) # Output: {'name': 'Diana', 'age': 22}
  4. Empty Dictionary :
    empty_dict = {} # or 
    empty_dict = dict()
    print(empty_dict) # Output: {}

Key Characteristics of Dictionaries

link to this section
  • Unordered : Prior to Python 3.7, dictionaries were unordered. Since Python 3.7, they maintain insertion order (though this isn’t a guarantee for sorting).
  • Mutable : You can add, update, or remove key-value pairs.
  • Unique Keys : Duplicate keys aren’t allowed; the last assignment overwrites earlier ones.
  • Hashable Keys : Keys must be immutable types (e.g., strings, integers, tuples).

Example of duplicate keys:

my_dict = {"key": 1, "key": 2}
print(my_dict) # Output: {'key': 2}

Accessing Dictionary Elements

link to this section

You can access values using keys:

  • Square Brackets : dict[key] – Raises KeyError if the key doesn’t exist.
    person = {"name": "Eve", "age": 27}
    print(person["name"]) # Output: Eve
  • get() Method : dict.get(key, default) – Returns None or a default value if the key isn’t found.
    print(person.get("age")) # Output: 27
    print(person.get("city", "Unknown")) # Output: Unknown

Python Dictionary Methods

link to this section

Dictionaries come with a robust set of methods. Below is a complete list with detailed explanations and examples.

1. clear() – Remove All Items

Empties the dictionary.

  • Syntax : dict.clear()
  • Example :
    person = {"name": "Frank", "age": 35} 
    person.clear()
    print(person) # Output: {}

2. copy() – Create a Shallow Copy

Returns a new dictionary with the same key-value pairs.

  • Syntax : dict.copy()
  • Example :
    person = {"name": "Grace", "age": 29} 
    person_copy = person.copy() 
    person["name"] = "Helen"
    print(person) # Output: {'name': 'Helen', 'age': 29}
    print(person_copy) # Output: {'name': 'Grace', 'age': 29}

3. get() – Retrieve a Value

Returns the value for a key, or a default if the key isn’t found.

  • Syntax : dict.get(key, default=None)
  • Example :
    person = {"name": "Ivy"}
    print(person.get("name")) # Output: Ivy
    print(person.get("age", 0)) # Output: 0

4. items() – View Key-Value Pairs

Returns a view of the dictionary’s key-value pairs as tuples.

  • Syntax : dict.items()
  • Example :
    person = {"name": "Jack", "age": 33}
    print(person.items()) # Output: dict_items([('name', 'Jack'), ('age', 33)]) 
    for key, value in person.items():
        print(f"{key}: {value}") 
    # Output: # name: Jack # age: 33

5. keys() – View All Keys

Returns a view of the dictionary’s keys.

  • Syntax : dict.keys()
  • Example :
    person = {"name": "Kelly", "age": 24}
    print(person.keys()) # Output: dict_keys(['name', 'age'])
    print(list(person.keys())) # Output: ['name', 'age']

6. values() – View All Values

Returns a view of the dictionary’s values.

  • Syntax : dict.values()
  • Example :
    person = {"name": "Liam", "age": 31}
    print(person.values()) # Output: dict_values(['Liam', 31])
    print(list(person.values())) # Output: ['Liam', 31]

7. pop() – Remove and Return a Value

Removes a key and returns its value; raises KeyError if the key isn’t found.

  • Syntax : dict.pop(key, default)
  • Example :
    person = {"name": "Mia", "age": 26} 
    age = person.pop("age")
    print(age) # Output: 26
    print(person) # Output: {'name': 'Mia'}

8. popitem() – Remove and Return Last Pair

Removes and returns the last key-value pair as a tuple (Python 3.7+ maintains insertion order).

  • Syntax : dict.popitem()
  • Example :
    person = {"name": "Noah", "age": 28} 
    item = person.popitem()
    print(item) # Output: ('age', 28)
    print(person) # Output: {'name': 'Noah'}

9. update() – Add or Update Key-Value Pairs

Updates the dictionary with key-value pairs from another dictionary or iterable.

  • Syntax : dict.update(other)
  • Example :
    person = {"name": "Olivia"} 
    person.update({"age": 23, "city": "Boston"})
    print(person) # Output: {'name': 'Olivia', 'age': 23, 'city': 'Boston'}

10. setdefault() – Get or Set Default Value

Returns the value for a key; if the key doesn’t exist, inserts it with a default value.

  • Syntax : dict.setdefault(key, default=None)
  • Example :
    person = {"name": "Paul"} 
    age = person.setdefault("age", 25)
    print(age) # Output: 25
    print(person) # Output: {'name': 'Paul', 'age': 25}

11. fromkeys() – Create a Dictionary from Keys

Creates a new dictionary with specified keys and a common value (class method).

  • Syntax : dict.fromkeys(keys, value=None)
  • Example :
    keys = ["name", "age", "city"] 
    new_dict = dict.fromkeys(keys, "Unknown")
    print(new_dict) # Output: {'name': 'Unknown', 'age': 'Unknown', 'city': 'Unknown'}

Dictionary Operations

link to this section

Beyond methods, dictionaries support useful operations:

  • Membership Test : key in dict – Check if a key exists.
    person = {"name": "Quinn"}
    print("name" in person) # Output: True
  • Length : len(dict) – Number of key-value pairs.
    print(len(person)) # Output: 1
  • Assignment : Add or update with dict[key] = value.
    person["age"] = 22
    print(person) # Output: {'name': 'Quinn', 'age': 22}

Nested Dictionaries

link to this section

Dictionaries can contain other dictionaries for hierarchical data:

students = { 
    "student1": {"name": "Rose", "age": 20}, 
    "student2": {"name": "Sam", "age": 21} 
}
print(students["student1"]["name"]) # Output: Rose

Performance Insights

link to this section
  • Time Complexity : Most operations (e.g., access, insertion, deletion) are O(1) on average due to hash table implementation. Collisions can degrade to O(n) in rare cases.
  • Memory : Dictionaries use more memory than lists due to hashing but offer faster lookups.
  • Order : Since Python 3.7, insertion order is preserved, making dictionaries more predictable.

Practical Use Cases

link to this section
  1. Storing Configuration Data :
    config = {"host": "localhost", "port": 8080}
    print(config["host"]) # Output: localhost
  2. Counting Frequencies :
    words = ["apple", "banana", "apple"] 
    freq = {} 
    for word in words: 
        freq[word] = freq.get(word, 0) + 1
    print(freq) # Output: {'apple': 2, 'banana': 1}
  3. Mapping Relationships :
    capitals = {"USA": "Washington", "France": "Paris"}
    print(capitals["France"]) # Output: Paris
  4. Nested Data Storage :
    employees = { 
        "e1": {"name": "Tom", "dept": "IT"}, 
        "e2": {"name": "Uma", "dept": "HR"}
    }
    print(employees["e1"]["dept"]) # Output: IT

Common Pitfalls and Solutions

link to this section
  1. KeyError :
    • Problem : Accessing a non-existent key:
      d = {"name": "Vera"}
      print(d["age"]) # KeyError: 'age'
    • Solution : Use get():
      print(d.get("age", "N/A")) # Output: N/A
  2. Mutable Default Values :
    • Problem : Using a mutable default in setdefault():
      d = {} 
      d.setdefault("list", []).append(1) 
      d.setdefault("list", []).append(2)
      print(d) # Output: {'list': [1, 2]}
    • Solution : Define defaults explicitly:
      d = {} 
      if "list" not in d: 
          d["list"] = [] 
      d["list"].append(1)
  3. Overwriting Keys :
    • Problem : Duplicate keys overwrite:
      d = {"key": 1, "key": 2}
      print(d) # Output: {'key': 2}
    • Solution : Use unique keys or nested structures.

Conclusion

link to this section

Python dictionaries are a cornerstone of efficient data management, offering a flexible way to store and retrieve key-value pairs. With methods like get(), items(), and update(), plus their ability to handle nested data, dictionaries are indispensable for a wide range of tasks. Whether you’re counting occurrences, mapping data, or structuring complex information, mastering dictionaries will elevate your Python skills.

Try the examples above in your projects to see their power firsthand. Have a favorite dictionary trick? I’d love to hear about it!