Python - Get All Keys/Values as List

• Python dictionaries provide `keys()`, `values()`, and `items()` methods that return view objects, which can be converted to lists using `list()` constructor for manipulation and iteration

Key Insights

• Python dictionaries provide keys(), values(), and items() methods that return view objects, which can be converted to lists using list() constructor for manipulation and iteration • Dictionary views are dynamic and reflect changes to the underlying dictionary, while converted lists are static snapshots at the time of conversion • Performance considerations matter: view objects are memory-efficient for iteration, but list conversion is necessary for indexing, slicing, and operations requiring multiple passes

Understanding Dictionary View Objects

When you call keys(), values(), or items() on a dictionary, Python returns view objects rather than lists. These views provide a dynamic window into the dictionary’s data.

user_data = {
    'username': 'john_doe',
    'email': 'john@example.com',
    'age': 30,
    'active': True
}

keys_view = user_data.keys()
values_view = user_data.values()
items_view = user_data.items()

print(type(keys_view))    # <class 'dict_keys'>
print(type(values_view))  # <class 'dict_values'>
print(type(items_view))   # <class 'dict_items'>

View objects are iterable but don’t support indexing. To access elements by position or perform list-specific operations, convert them to lists.

Converting Keys to a List

The most straightforward approach uses the list() constructor:

config = {
    'database': 'postgresql',
    'host': 'localhost',
    'port': 5432,
    'timeout': 30
}

keys_list = list(config.keys())
print(keys_list)  # ['database', 'host', 'port', 'timeout']

# Now you can use list operations
print(keys_list[0])      # 'database'
print(keys_list[-1])     # 'timeout'
print(keys_list[1:3])    # ['host', 'port']

For scenarios requiring sorted keys:

api_endpoints = {
    'users': '/api/v1/users',
    'posts': '/api/v1/posts',
    'comments': '/api/v1/comments',
    'auth': '/api/v1/auth'
}

sorted_keys = sorted(api_endpoints.keys())
print(sorted_keys)  # ['auth', 'comments', 'posts', 'users']

# Alternative: sort in reverse
reverse_sorted = sorted(api_endpoints.keys(), reverse=True)
print(reverse_sorted)  # ['users', 'posts', 'comments', 'auth']

Converting Values to a List

Values extraction follows the same pattern:

metrics = {
    'cpu_usage': 75.5,
    'memory_usage': 82.3,
    'disk_usage': 45.1,
    'network_latency': 12.8
}

values_list = list(metrics.values())
print(values_list)  # [75.5, 82.3, 45.1, 12.8]

# Perform calculations on values
average = sum(values_list) / len(values_list)
print(f"Average: {average:.2f}")  # Average: 53.92

max_value = max(values_list)
print(f"Maximum: {max_value}")  # Maximum: 82.3

When working with nested dictionaries:

servers = {
    'web-01': {'cpu': 45, 'memory': 60},
    'web-02': {'cpu': 52, 'memory': 58},
    'db-01': {'cpu': 78, 'memory': 85}
}

server_configs = list(servers.values())
print(server_configs)
# [{'cpu': 45, 'memory': 60}, {'cpu': 52, 'memory': 58}, {'cpu': 78, 'memory': 85}]

# Extract specific nested values
cpu_values = [config['cpu'] for config in server_configs]
print(cpu_values)  # [45, 52, 78]

Working with Key-Value Pairs

The items() method returns tuples of key-value pairs:

user_permissions = {
    'read': True,
    'write': False,
    'delete': False,
    'admin': True
}

items_list = list(user_permissions.items())
print(items_list)
# [('read', True), ('write', False), ('delete', False), ('admin', True)]

# Filter based on values
active_permissions = [key for key, value in items_list if value]
print(active_permissions)  # ['read', 'admin']

# Unpack and process
for permission, enabled in items_list:
    status = "enabled" if enabled else "disabled"
    print(f"{permission}: {status}")

Converting items to separate lists:

product_prices = {
    'laptop': 1299.99,
    'mouse': 29.99,
    'keyboard': 89.99,
    'monitor': 399.99
}

items = list(product_prices.items())
keys, values = zip(*items)  # Unzip into separate tuples

keys_list = list(keys)
values_list = list(values)

print(keys_list)    # ['laptop', 'mouse', 'keyboard', 'monitor']
print(values_list)  # [1299.99, 29.99, 89.99, 399.99]

List Comprehension Alternatives

List comprehensions offer concise syntax with built-in filtering and transformation:

inventory = {
    'apples': 50,
    'bananas': 30,
    'oranges': 0,
    'grapes': 25,
    'strawberries': 0
}

# Keys where value is greater than zero
available_items = [item for item in inventory.keys() if inventory[item] > 0]
print(available_items)  # ['apples', 'bananas', 'grapes']

# Values with transformation
doubled_quantities = [qty * 2 for qty in inventory.values()]
print(doubled_quantities)  # [100, 60, 0, 50, 0]

# Key-value pairs with condition
low_stock = [(item, qty) for item, qty in inventory.items() if 0 < qty < 40]
print(low_stock)  # [('bananas', 30), ('grapes', 25)]

Transform keys during conversion:

raw_data = {
    'firstName': 'Alice',
    'lastName': 'Smith',
    'emailAddress': 'alice@example.com'
}

# Convert camelCase keys to snake_case
import re

def camel_to_snake(name):
    return re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()

snake_case_keys = [camel_to_snake(key) for key in raw_data.keys()]
print(snake_case_keys)  # ['first_name', 'last_name', 'email_address']

Performance Considerations

View objects are memory-efficient for single-pass iterations:

large_dict = {f'key_{i}': i for i in range(1000000)}

# Memory-efficient: iterates without creating a list
for key in large_dict.keys():
    if key.startswith('key_999'):
        print(key)

# Less efficient: creates a list in memory
keys_list = list(large_dict.keys())
for key in keys_list:
    if key.startswith('key_999'):
        print(key)

Use list conversion when you need:

cache = {
    'user_123': {'name': 'Alice', 'last_access': 1234567890},
    'user_456': {'name': 'Bob', 'last_access': 1234567891},
    'user_789': {'name': 'Charlie', 'last_access': 1234567892}
}

keys_list = list(cache.keys())

# Indexing
first_key = keys_list[0]

# Slicing
first_two = keys_list[:2]

# Multiple iterations
for key in keys_list:
    print(f"First pass: {key}")
    
for key in keys_list:
    print(f"Second pass: {key}")

# Modification during iteration (safer with list)
for key in keys_list:
    if cache[key]['last_access'] < 1234567891:
        del cache[key]

Practical Application: Dictionary Merging

Combine multiple dictionaries using keys and values as lists:

default_config = {'timeout': 30, 'retries': 3, 'debug': False}
user_config = {'timeout': 60, 'debug': True}
env_config = {'retries': 5, 'api_key': 'secret'}

# Merge with priority
all_keys = set(list(default_config.keys()) + 
               list(user_config.keys()) + 
               list(env_config.keys()))

merged = {}
for key in all_keys:
    if key in env_config:
        merged[key] = env_config[key]
    elif key in user_config:
        merged[key] = user_config[key]
    else:
        merged[key] = default_config[key]

print(merged)
# {'timeout': 60, 'retries': 5, 'debug': True, 'api_key': 'secret'}

This approach gives you complete control over dictionary data extraction and manipulation in Python. Choose view objects for memory efficiency and single iterations, and convert to lists when you need indexing, slicing, or multiple passes over the data.

Liked this? There's more.

Every week: one practical technique, explained simply, with code you can use immediately.