Skip to main content

How to Count Dictionaries in a List in Python

When working with lists that contain mixed data types, you may need to isolate and count only the dictionary objects. This is a common scenario when parsing JSON responses, processing configuration data, or handling records from various sources where the list structure is not guaranteed to be uniform.

In this guide, you will learn multiple ways to count dictionaries in a list in Python, from simple one-liners to recursive approaches for deeply nested structures. Each method is explained with examples and output so you can choose the right one for your specific use case.

Using a Generator Expression with sum()

The most memory-efficient approach uses a generator expression with sum(). It processes elements one at a time without creating any intermediate list in memory:

data = [1, "text", {"id": 1}, [10, 20], {"id": 2}]

count = sum(1 for item in data if isinstance(item, dict))

print(count)

Output:

2

The generator yields 1 for every element that is a dictionary and sum() adds them up. Since no intermediate collection is created, this approach is well suited for large lists where memory efficiency matters.

Using List Comprehension with len()

When you need both the count and access to the actual dictionary objects for further processing, a list comprehension is the better choice:

data = [1, {"a": 1}, {"b": 2}, "string", 42]

dicts = [item for item in data if isinstance(item, dict)]

print(len(dicts))
print(dicts)

Output:

2
[{'a': 1}, {'b': 2}]

This approach builds a new list containing only the dictionaries, which you can then iterate over, modify, or pass to other functions. The trade-off is higher memory usage compared to the generator expression, since all matching items are stored in a list at once.

Using the filter() Function

The filter() function offers a functional programming style to achieve the same result:

data = [1, {"a": 1}, None, {"b": 2}]

dict_filter = filter(lambda x: isinstance(x, dict), data)
count = len(list(dict_filter))

print(count)

Output:

2
note

The filter() function returns a lazy iterator, so you must convert it to a list before calling len(). For simple counting tasks, the generator expression with sum() is more straightforward and avoids the extra conversion step.

Using a for Loop

A traditional for loop with a counter variable is the most explicit approach. It is easy to read and works well when you need to add extra logic during iteration:

data = [1, {"a": 1}, "hello", {"b": 2}, None, {"c": 3}]

count = 0
for item in data:
if isinstance(item, dict):
count += 1

print(count)

Output:

3

While more verbose than a one-liner, this pattern is straightforward for beginners and makes it easy to add logging, filtering conditions, or side effects inside the loop body.

Counting Dictionaries Recursively in Nested Structures

For nested structures containing lists within lists or dictionaries within dictionaries, a recursive function can find all dictionaries at any depth:

def count_dicts(obj):
"""Count all dictionaries in a nested structure."""
if isinstance(obj, dict):
# Count this dict plus any dicts nested in its values
return 1 + sum(count_dicts(value) for value in obj.values())
elif isinstance(obj, list):
# Sum counts from all list elements
return sum(count_dicts(item) for item in obj)
return 0

nested = [1, {"key": {"inner": 1}}, [{}, {}]]

print(count_dicts(nested))

Output:

4

The count breaks down as follows:

  • {"key": {"inner": 1}} counts as 1 outer dict + 1 inner dict = 2
  • [{}, {}] counts as 2 empty dicts
  • Total: 4 dictionaries
Counting Only Top-Level Dictionaries in Nested Lists

If you want to count dictionaries inside nested lists but do not want to descend into dictionary values, modify the recursive function like this:

def count_dicts_shallow(obj):
if isinstance(obj, dict):
return 1
elif isinstance(obj, list):
return sum(count_dicts_shallow(item) for item in obj)
return 0

nested = [1, {"key": {"inner": 1}}, [{}, {}]]

print(count_dicts_shallow(nested))

Output:

3

This version counts {"key": {"inner": 1}} as a single dictionary and does not look inside its values.

Why You Should Use isinstance() Instead of type()

When checking for dictionaries, always prefer isinstance(x, dict) over type(x) == dict. The reason is that isinstance() correctly recognizes subclasses of dict, while type() only matches the exact class.

Here is a practical example showing the difference:

from collections import OrderedDict

data = [{"a": 1}, OrderedDict([("b", 2)])]

# isinstance catches dict subclasses
print(sum(1 for x in data if isinstance(x, dict)))

# type() misses subclasses
print(sum(1 for x in data if type(x) == dict))

Output:

2
1

Since OrderedDict is a subclass of dict, the type() check fails to count it. In real-world code, many libraries return dict subclasses (such as OrderedDict, defaultdict, or custom mapping types), so isinstance() is the safer and more robust choice.

warning

Using type(x) == dict can lead to subtle bugs that are hard to track down, especially when your data comes from third-party libraries or serialization frameworks that may return dict subclasses. Stick with isinstance() unless you have a very specific reason to match the exact type.

Method Comparison

MethodBest Use CaseMemory Usage
Generator expression with sum()Count only, no need to keep itemsLow
List comprehension with len()Need the dicts for further processingHigher
filter() with len(list(...))Functional programming styleHigher
for loop with counterCustom logic during iterationLow
Recursive functionNested or deeply structured dataStack-dependent

Conclusion

For straightforward counting tasks, the generator expression with sum() is the most efficient and Pythonic approach. Use a list comprehension when you need to both count and retain the dictionary objects for further processing. A traditional for loop is ideal when you need to perform additional operations during iteration. For deeply nested data structures, a recursive function ensures no dictionary is missed regardless of nesting depth.

Regardless of which method you choose, always use isinstance(x, dict) instead of type(x) == dict to correctly handle dictionary subclasses and avoid hard-to-find bugs.