How to Choose Between Lists and Dictionaries in Python
Lists and dictionaries serve fundamentally different purposes. Lists store ordered sequences accessed by position, while dictionaries store key-value pairs accessed by meaningful identifiers. Choosing correctly impacts both code clarity and performance.
Core Differences
| Feature | List | Dictionary |
|---|---|---|
| Access Method | By index [0] | By key ["name"] |
| Lookup Speed | O(n) scan | O(1) hash |
| Order Preserved | ✅ Always | ✅ Python 3.7+ |
| Duplicates | ✅ Allowed | ❌ Keys unique |
When to Use Lists
Lists excel when position matters or you're working with sequential data:
# Ordered steps
steps = ["Download", "Install", "Configure", "Run"]
first_step = steps[0] # "Download"
# Numeric sequences
temperatures = [72, 75, 68, 71, 73]
average = sum(temperatures) / len(temperatures)
# Items where order matters
queue = ["Alice", "Bob", "Charlie"]
next_person = queue.pop(0)
When to Use Dictionaries
Dictionaries shine when you need fast lookups by meaningful keys:
# Named attributes
user = {"name": "Alice", "email": "alice@example.com", "age": 30}
print(user["email"]) # Instant access
# Configuration settings
config = {"debug": True, "max_connections": 100, "timeout": 30}
if config["debug"]:
# for example invoke your logger...
enable_logging()
# Counting occurrences
word_count = {}
for word in text.split():
word_count[word] = word_count.get(word, 0) + 1
The Lookup Performance Gap
This difference becomes critical with large datasets:
# Searching in a list - O(n)
users_list = ["alice", "bob", "charlie", ...] # 10,000 users
if "zachary" in users_list: # Scans up to 10,000 items
print("Found")
# Searching in a dict - O(1)
users_dict = {"alice": True, "bob": True, ...} # 10,000 users
if "zachary" in users_dict: # Single hash lookup
print("Found")
When you frequently check if items exist in a collection, convert your list to a set or dictionary:
# Before: slow repeated lookups
valid_codes = ["A1", "B2", "C3", ...]
for code in input_codes:
if code in valid_codes: # O(n) each time
process(code)
# After: fast lookups
valid_codes = {"A1", "B2", "C3", ...} # or set(valid_codes)
for code in input_codes:
if code in valid_codes: # O(1) each time
process(code)
Common Patterns
List of Dictionaries
Combine both for tabular data:
employees = [
{"id": 1, "name": "Alice", "role": "Engineer"},
{"id": 2, "name": "Bob", "role": "Designer"},
{"id": 3, "name": "Charlie", "role": "Manager"}
]
# Access by position, then by key
first_employee_name = employees[0]["name"]
# Filter with comprehension
engineers = [e for e in employees if e["role"] == "Engineer"]
Dictionary for Fast Lookups
Convert list to dictionary when you need repeated access by a specific field:
# Slow: finding user by ID requires scanning
users = [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]
def find_user(user_id):
for user in users:
if user["id"] == user_id:
return user
# Fast: direct access by ID
users_by_id = {user["id"]: user for user in users}
alice = users_by_id[1] # Instant
Decision Guide
| Scenario | Best Choice |
|---|---|
| Sequential data | List |
| Accessing by position | List |
| Need fast lookups by identifier | Dictionary |
| Named/labeled data | Dictionary |
| Counting or grouping | Dictionary |
| Maintaining insertion order only | List |
Summary
- Lists: Ordered sequences accessed by numeric index
- Dictionaries: Key-value mappings with O(1) lookups
Choose lists when position matters. Choose dictionaries when you need fast access by meaningful keys. For large collections with frequent membership testing, the performance difference is substantial.