Explain Codes LogoExplain Codes Logo

Getting a list of values from a list of dicts

python
list-comprehension
memory-efficiency
data-extraction
Anton ShumikhinbyAnton Shumikhin·Feb 8, 2025
TLDR

In Python, we use list comprehensions for rapid extraction of values from lists of dictionaries. Consider the following code:

values = [d['key'] for d in list_of_dicts if 'key' in d]

This one-line solution creates a new list, values, containing values associated with the 'key' from each dictionary in list_of_dicts. Just replace 'key' with the actual key you're interested in.

Effective usage and error handling in list comprehension

When working with real-world data, it’s not always guaranteed that every dictionary will contain your key. To handle this situation, use get(). This function provides a default value for missing keys as demonstrated here:

values = [d.get('key', 'None') for d in list_of_dicts]

Tip: Inside the get() function, replace None with any default value you want to use when the key is missing to avoid KeyError.

Memory-efficient solution for large datasets

For large datasets, we should consider memory use. A list comprehension will create an entire list in memory, but we can use a generator expression to create values as needed:

values_gen = (d.get('key', 'None') for d in list_of_dicts)

values_gen is an iterable; you can run through all its elements just like a list without occupying memory.

Advanced dictionary digging

For more complex dictionary structures, we have the power of libraries like dpath or jsonpath-ng. Consider these the digs deep tools for extracting your needful data from the nested dictionary rubble:

# Exploit your dictionary like never before from jsonpath_ng import jsonpath, parse jsonpath_expression = parse('$.store.book[*].author') authors = [match.value for match in jsonpath_expression.find(json_document)]

This advanced pattern matching can be a powerful tool for mining data from deeply nested dictionaries.

Converting lazy to eager and the quest for clean code

Python 3 has changed the map() and filter() functions to return lazy iterators instead of lists. When you need a list, only then explicitly convert them:

# Remember what they said about assumptions? Yeah, don't. values_mapped = list(map(lambda x: x.get('key', 'default_value'), list_of_dicts))

Although lambdas can get the job done, for readability consider using operator.itemgetter() or dedicated functions:

# A classy code is a clean code from operator import itemgetter values_mapped = list(map(itemgetter('key'), list_of_dicts))

And as Uncle Bob said, readability trumps cleverness every day of the week.

Filtering data with finesse

The built-in filter() function is another handy tool for extracting values. Combined with a predicate function, it adds another layer of control:

# Like a bouncer for your club of values 💪 def has_truthy_value(d, key): return key in d and bool(d[key]) filtered_values = [d[key] for d in filter(lambda x: has_truthy_value(x, 'key'), list_of_dicts)]

Achieves the same goal, more efficiently, more Pythonically.