How to Count Keys with a Given Value in a Python Dictionary
A common task when working with dictionaries is counting how many keys share a specific value. For example, given a dictionary of student grades, you might want to know how many students received a particular score.
Consider this example:
- Input:
{'a': 5, 'b': 3, 'c': 5, 'd': 7, 'e': 5}, target valuen = 5 - Output:
3(keys'a','c', and'e'all have the value5)
In this guide, you will learn several approaches to solve this problem, from the most concise and memory-efficient to the most flexible. Each method is demonstrated with clear examples and output.
Using sum() with a Generator Expression (Recommended)
The most Pythonic and memory-efficient approach uses a generator expression with sum(). The generator yields 1 for each matching value, and sum() adds them up:
data = {'a': 5, 'b': 3, 'c': 5, 'd': 7, 'e': 5}
n = 5
count = sum(1 for v in data.values() if v == n)
print(count)
Output:
3
data.values() extracts all values from the dictionary. The generator expression checks each value against n and yields 1 for every match. sum() totals those ones to produce the final count.
Unlike list-based approaches, the generator expression does not create an intermediate list in memory. It processes values one at a time, making it efficient even for very large dictionaries.
An equivalent and slightly more concise version uses boolean counting, taking advantage of the fact that Python treats True as 1 and False as 0 in arithmetic:
data = {'a': 5, 'b': 3, 'c': 5, 'd': 7, 'e': 5}
n = 5
count = sum(v == n for v in data.values())
print(count)
Output:
3
Using Counter from collections
The Counter class builds a complete frequency map of all values in a single pass. You can then look up the count for any specific value in O(1) time:
from collections import Counter
data = {'a': 5, 'b': 3, 'c': 5, 'd': 7, 'e': 5}
n = 5
count = Counter(data.values())[n]
print(count)
Output:
3
Counter(data.values()) creates a frequency dictionary like {5: 3, 3: 1, 7: 1}, and accessing [n] returns the count for that value.
This approach is especially powerful when you need to check counts for multiple values, since the frequency map is built once and each lookup afterward is O(1):
from collections import Counter
data = {'a': 5, 'b': 3, 'c': 5, 'd': 7, 'e': 5, 'f': 3}
freq = Counter(data.values())
print(f"Value 5 appears {freq[5]} times")
print(f"Value 3 appears {freq[3]} times")
print(f"Value 9 appears {freq[9]} times")
Output:
Value 5 appears 3 times
Value 3 appears 2 times
Value 9 appears 0 times
Like all Counter objects, missing keys return 0 instead of raising a KeyError.
Using .count() on Values
Convert the dictionary values to a list and use the built-in .count() method for a quick one-liner:
data = {'a': 5, 'b': 3, 'c': 5, 'd': 7, 'e': 5}
n = 5
count = list(data.values()).count(n)
print(count)
Output:
3
This is concise and easy to read, but it creates an intermediate list in memory, which is less efficient than the generator approach for very large dictionaries.
Using List Comprehension with len()
If you need the matching keys themselves in addition to the count, a list comprehension gives you both:
data = {'a': 5, 'b': 3, 'c': 5, 'd': 7, 'e': 5}
n = 5
matching_keys = [k for k, v in data.items() if v == n]
count = len(matching_keys)
print(f"Count: {count}")
print(f"Keys: {matching_keys}")
Output:
Count: 3
Keys: ['a', 'c', 'e']
This approach is the right choice when you need to know not just how many keys match, but which specific keys they are.
Practical Example: Counting Student Grades
Here is a real-world scenario that combines multiple techniques to count how many students received each grade:
from collections import Counter
grades = {
'Alice': 'A',
'Bob': 'B',
'Charlie': 'A',
'Diana': 'C',
'Eve': 'A',
'Frank': 'B'
}
# Count students with a specific grade
a_count = sum(1 for v in grades.values() if v == 'A')
print(f"Students with grade A: {a_count}")
# Get a full breakdown of all grades
breakdown = Counter(grades.values())
for grade, count in sorted(breakdown.items()):
print(f" Grade {grade}: {count} student(s)")
# Find which students got an A
a_students = [name for name, grade in grades.items() if grade == 'A']
print(f"A students: {a_students}")
Output:
Students with grade A: 3
Grade A: 3 student(s)
Grade B: 2 student(s)
Grade C: 1 student(s)
A students: ['Alice', 'Charlie', 'Eve']
Method Comparison
| Method | Creates Intermediate Data | Returns Matching Keys | Best For |
|---|---|---|---|
sum() + generator | No (memory efficient) | No | Single value count (recommended) |
Counter | Yes (frequency map) | No | Counting multiple values |
list().count() | Yes (list copy) | No | Quick one-liner |
List comprehension + len() | Yes (filtered list) | Yes | When you need the matching keys |
Conclusion
For counting how many keys share a specific value, the sum() with a generator expression approach is the best default choice. It is concise, memory-efficient, and handles dictionaries of any size.
- Use
Counterwhen you need to query counts for multiple different values, since it builds the frequency map once and provides O(1) lookups afterward. - Use list comprehension with
len()when you need both the count and the actual matching keys.
All approaches produce the same count. Choose based on whether you need memory efficiency, multiple lookups, or access to the matching keys themselves.