Dictionaries & Sets

When you need to store data that isn't just a simple sequence, Python offers powerful alternatives to lists and tuples: dictionaries and sets. Dictionaries allow you to associate values with unique keys, much like a real-world dictionary maps words to definitions. Sets, on the other hand, are collections of unique items, ideal for membership testing and mathematical set operations. Mastering these structures is crucial for efficient data management in Python.

Understanding Dictionaries

A dictionary in Python is an unordered collection of items, where each item is a key-value pair. Unlike sequences (lists, tuples) which are indexed by a range of numbers, dictionaries are indexed by keys, which can be any immutable type like strings, numbers, or tuples. This structure makes dictionaries incredibly efficient for retrieving a value when you know its corresponding key, offering near-constant time complexity for lookups. They are mutable, meaning you can add, remove, and modify key-value pairs after creation.

Dictionary (dict)
An unordered, mutable collection of unique key-value pairs. Keys must be immutable and unique; values can be of any type.
Example: python user_profile = { "username": "data_analyst_23", "email": "analyst@example.com", "is_active": True }

Creating and Initializing Dictionaries

Dictionaries are typically created using curly braces {} with key-value pairs separated by colons, and pairs separated by commas. You can also use the dict() constructor, which is useful for creating dictionaries from sequences of key-value tuples or keyword arguments. Starting with an empty dictionary and adding elements later is a common pattern when building data dynamically.

pythonCreating Dictionaries with Different Methods

Accessing and Retrieving Values

To retrieve a value from a dictionary, you use the key inside square brackets, similar to how you access elements in a list by index. This direct lookup is incredibly fast. However, if you try to access a key that does not exist in the dictionary, Python will raise a KeyError. This behavior is important to anticipate and handle in your code to prevent runtime crashes.

pythonAccessing Dictionary Values by Key
⚠️ Handling KeyError

Attempting to access a dictionary key that does not exist using my_dict[key] will immediately raise a KeyError and stop your program. Always use if key in my_dict: or the get() method to safely retrieve values if the key's presence is uncertain.

Adding, Updating, and Deleting Entries

Dictionaries are mutable, allowing you to change their contents after creation. To add a new key-value pair, simply assign a value to a new key using bracket notation. If the key already exists, this same assignment operation will update its corresponding value. You can remove key-value pairs using the del keyword or the pop() method, which also returns the value of the removed item.

pythonModifying Dictionary Contents

The get() Method for Safe Access

The get() method provides a safer way to access dictionary values than direct bracket notation. If the key exists, get() returns its corresponding value. If the key does not exist, get() returns None by default, rather than raising a KeyError. You can also provide a second argument to get(), which will be returned as a default value if the key is not found. This is incredibly useful for handling optional data or configurations.

pythonUsing `get()` for Robust Dictionary Access
Check Your Understanding
You have a dictionary config = {'debug': True, 'log_level': 'INFO'}. What happens if you execute config['timeout'] = 30 and then config.get('timeout', 60)?

Iterating Through Dictionaries

You often need to process all items in a dictionary. Python provides several ways to iterate. By default, a for loop over a dictionary iterates through its keys. You can explicitly get an iterable view of keys, values, or key-value pairs (items) using the keys(), values(), and items() methods, respectively. Iterating through items() is particularly common as it provides both the key and value simultaneously, often unpacked into two loop variables.

pythonLooping Over Dictionary Keys, Values, and Items

Dictionary Views: keys(), values(), items()

The keys(), values(), and items() methods return view objects, not actual lists. These view objects provide a dynamic, read-only window into the dictionary's contents. This means that if the dictionary changes after a view object is created, the view will reflect those changes immediately. This behavior is memory-efficient, as it avoids creating a full copy of the keys or values, and ensures that your iterations always work with the most current state of the dictionary.

pythonDynamic Nature of Dictionary View Objects
Try It Yourself
You're managing a small inventory system. Given an initial inventory dictionary, add a new item, update the stock of an existing item, and then calculate the total number of items in stock. Finally, print the updated inventory and the total stock.
python

Introducing Sets

A set is an unordered collection of unique elements. This uniqueness is the defining characteristic of sets; any duplicate elements added will automatically be discarded. Sets are highly optimized for checking membership (is an item in the set?) and performing mathematical set operations like union, intersection, and difference. Like dictionaries, sets are mutable, allowing elements to be added or removed after creation, but they do not support indexing or slicing because they are unordered.

Set (set)
An unordered, mutable collection of unique, hashable elements. Used for membership testing and mathematical set operations.
Example: python active_users = {"Alice", "Bob", "Charlie"}

Creating and Initializing Sets

Sets can be created using curly braces {} containing comma-separated elements, similar to dictionaries, but without key-value pairs. Alternatively, the set() constructor can convert other iterable objects, like lists or tuples, into a set. When converting from an iterable, any duplicate elements present in the original iterable will be automatically removed, leaving only unique items in the resulting set. Remember that an empty set must be created using set(), not {}.

pythonCreating Sets and Handling Duplicates
📌 Empty Set vs. Empty Dictionary

Remember that {} creates an empty dictionary, not an empty set. To create an empty set, you must use set().

Adding and Removing Set Elements

Sets are mutable, so you can add new elements using the add() method. If you try to add an element that is already present, the set remains unchanged, upholding its uniqueness property. To remove elements, you have a choice between remove() and discard(). remove() will raise a KeyError if the element is not found, while discard() will do nothing, making it a safer option when you're unsure if an element exists. The pop() method removes and returns an arbitrary element, as sets are unordered.

pythonModifying Elements in a Set

Essential Set Operations

Sets excel at performing mathematical set operations, which are fundamental in many data analysis and logic tasks. The union of two sets combines all unique elements from both. The intersection finds elements common to both sets. The difference identifies elements present in one set but not the other. Finally, the symmetric difference returns elements that are in either set, but not in both. These operations can be performed using dedicated methods or intuitive operators.

pythonPerforming Set Operations (Union, Intersection, Difference)
Check Your Understanding
You have a list of sensor readings readings = [22.5, 23.1, 22.5, 24.0, 23.1]. If you convert this list to a set, what will be the length of the resulting set?

Immutability of Dictionary Keys and Set Elements

A critical requirement for dictionary keys and set elements is that they must be hashable. Hashable objects have a hash value that never changes during their lifetime and can be compared to other objects. Immutable types like numbers, strings, and tuples are hashable and thus can be used as dictionary keys or set elements. Mutable types like lists, dictionaries, and other sets are not hashable because their content can change, which would alter their hash value and break the internal lookup mechanism. This constraint ensures the integrity and efficiency of these data structures.

💡 Hashable Types

Common hashable (and thus valid for dictionary keys/set elements) types include: int, float, str, tuple, bool, None.

Common unhashable types (and thus invalid) include: list, dict, set.

Hashing and Performance Implications

The exceptional performance of dictionaries and sets for lookups, additions, and deletions stems from their underlying implementation using hash tables. When you add an item, its key (or the element itself for a set) is passed through a hash function, which computes an integer hash value. This hash value then determines where the item is stored in memory. When you try to retrieve an item, the same hash function is applied to the key, quickly pointing to its location. This process allows for average O(1) (constant time) operations, making them incredibly fast for large datasets, provided the hash function distributes keys well.

Choosing the Right Data Structure

Selecting the appropriate data structure is a fundamental decision in programming that impacts performance and code clarity. Lists are ideal for ordered sequences where element position matters and duplicates are allowed. Tuples are similar but immutable, making them suitable for fixed collections of related items. Dictionaries excel when you need to associate values with unique identifiers for fast lookups. Sets are the go-to choice for managing unique collections, performing membership tests, and executing mathematical set operations efficiently. Understanding these distinctions helps you write more effective and optimized Python code.

Comparing Python's Core Data Structures
FeatureListTupleDictionarySet
OrderOrdered (by insertion)Ordered (by insertion)Insertion-ordered (Python 3.7+)Unordered
MutabilityMutableImmutableMutableMutable
Duplicates AllowedYesYesNo (keys must be unique)No (elements must be unique)
Access MethodIndex (e.g., my_list[0])Index (e.g., my_tuple[0])Key (e.g., my_dict['key'])Membership test ('item' in my_set)
Typical Use CaseCollection of items, order mattersFixed collection of related itemsMapping unique keys to valuesCollection of unique items, membership tests
A quick reference for when to choose each fundamental Python data structure.
Check Your Understanding
You are building a system to track unique visitor IDs to a website and also store detailed profiles (name, email, last visit) for registered users. Which combination of data structures would be most appropriate?
Key Takeaways
  • Dictionaries store data as unordered, mutable key-value pairs, providing fast lookups by key (average O(1) time).

  • Dictionary keys must be unique and hashable (e.g., strings, numbers, tuples); values can be any type.

  • Use my_dict[key] for direct access (raises KeyError if key is missing) or my_dict.get(key, default) for safe access.

  • Sets store unordered, mutable collections of unique, hashable elements, ideal for membership testing and eliminating duplicates.

  • Use set() to create an empty set (not {}), and add(), remove(), or discard() to modify elements.

  • Sets support efficient mathematical operations like union() (|), intersection() (&), and difference() (-).

  • Choose dictionaries when you need to map unique identifiers to data, and sets when you need to manage unique items or perform set logic.

← All lessons in Python Basics & Syntax

Ready to keep this from fading?

Bitelrn turns lessons like this into a full course — quizzes, a knowledge map, and spaced review.

Get started free