Skip to content

How to Check if Value Exists in List of Dictionaries in Python

Learn Pythonic ways to check if a specific key-value pair exists in any dictionary within a list using any(), loops, and safe dictionary access with .get().

A common data structure in Python is a list containing multiple dictionaries, often representing records or objects (e.g., a list of users, products, etc.). A frequent task is to check if any dictionary within this list contains a specific key-value pair – essentially, searching for a record based on one of its attributes.

This guide demonstrates efficient and Pythonic ways to check if a specific value exists for a given key within any dictionary in a list, using any(), loops, and other techniques.

Understanding the Problem: Searching Within Nested Structures

We have a list where each item is a dictionary, like [{'id': 1, 'name': 'A'}, {'id': 2, 'name': 'B'}]. We want to know if any of these dictionaries contain a specific value (e.g., 'B') associated with a specific key (e.g., 'name').

Example Data:

users = [
    {'id': 'u001', 'name': 'Alice', 'status': 'active'},
    {'id': 'u002', 'name': 'Anna', 'status': 'inactive'},
    {'id': 'u003', 'name': 'Charlie', 'status': 'active'},
    {'id': 'u004', 'name': 'Anna', 'status': 'pending'} # Another Anna
]
search_key = 'name'
search_value = 'Anna'
value_not_present = 'David'

This is generally the most concise, readable, and efficient Pythonic way for checking existence.

Core Logic and Safety (.get())

  • Generator Expression: (d.get(search_key) == search_value for d in list_of_dicts) iterates through each dictionary (d) in the list.
  • .get(key, default): We use dictionary.get(search_key) instead of dictionary[search_key]. This is crucial because it safely handles dictionaries that might be missing the search_key. get() returns None (or a specified default) if the key is absent, preventing a KeyError. Direct access (d[search_key]) would crash if a dictionary lacked the key.
  • Comparison: It compares the value returned by .get() to our search_value.
  • any(iterable): Returns True as soon as the first dictionary yields True for the comparison (short-circuiting). Returns False if no dictionary matches or the list is empty.

Example Implementation

users = [
    {'id': 'u001', 'name': 'Alice', 'status': 'active'},
    {'id': 'u002', 'name': 'Anna', 'status': 'inactive'},
    {'id': 'u003', 'name': 'Charlie', 'status': 'active'},
]
search_key = 'name'
search_value = 'Anna'
value_not_present = 'David'

found_anna = any(user.get(search_key) == search_value for user in users)

print(f"Users: {users}")
print(f"Searching for {search_key} == '{search_value}'")
print(f"Found? {found_anna}") # Output: True

if found_anna:
    print("--> A dictionary with the specified value exists.") # This runs
else:
    print("--> No dictionary with the specified value exists.")

found_david = any(user.get(search_key) == value_not_present for user in users)
print(f"Searching for {search_key} == '{value_not_present}'")
print(f"Found? {found_david}") # Output: False

Output:

Users: [{'id': 'u001', 'name': 'Alice', 'status': 'active'}, {'id': 'u002', 'name': 'Anna', 'status': 'inactive'}, {'id': 'u003', 'name': 'Charlie', 'status': 'active'}]
Searching for name == 'Anna'
Found? True
--> A dictionary with the specified value exists.

Searching for name == 'David'
Found? False

Getting the First Matching Dictionary (:=)

To find the actual dictionary object that matched first (requires Python 3.8+):

users = [
    {'id': 'u001', 'name': 'Alice', 'status': 'active'},
    {'id': 'u002', 'name': 'Anna', 'status': 'inactive'},   # First match
    {'id': 'u004', 'name': 'Anna', 'status': 'pending'}     # Second match
]
search_key = 'name'
search_value = 'Anna'
matching_dict = None

if any((match := user).get(search_key) == search_value for user in users):
    print(f"Found a dictionary where {search_key} == '{search_value}'!")
    matching_dict = match
    print(f"The first matching dictionary is: {matching_dict}")
else:
    print(f"No dictionary found where {search_key} == '{search_value}'.")

print(f"Final value of matching_dict: {matching_dict}")

Output:

Found a dictionary where name == 'Anna'!
The first matching dictionary is: {'id': 'u002', 'name': 'Anna', 'status': 'inactive'}
Final value of matching_dict: {'id': 'u002', 'name': 'Anna', 'status': 'inactive'}

Method 2: Checking if a Value Does NOT Exist (not any())

To verify that no dictionary in the list has the specific key-value pair, simply negate the result of the any() call.

users = [
    {'id': 'u001', 'name': 'Alice', 'status': 'active'},
    {'id': 'u003', 'name': 'Charlie', 'status': 'active'},
]
search_key = 'name'
search_value = 'Anna' # Anna is not in this list

if not any(user.get(search_key) == search_value for user in users):
    print(f"Confirmed: No dictionary found where {search_key} == '{search_value}'.")
else:
    print(f"Found a dictionary where {search_key} == '{search_value}'.")

Output:

Confirmed: No dictionary found where name == 'Anna'.

Method 3: Using a for Loop

A standard for loop provides a more explicit way to iterate and check.

Core Logic

Initialize a flag (e.g., found = False). Loop through the list. In each iteration, check if the current dictionary has the target key and if its value matches. If a match is found, set the flag to True and break the loop (since we only need to know if at least one exists).

Example Implementation

users = [
    {'id': 'u001', 'name': 'Alice', 'status': 'active'},
    {'id': 'u002', 'name': 'Anna', 'status': 'inactive'},
    {'id': 'u003', 'name': 'Charlie', 'status': 'active'},
]
search_key = 'name'
search_value = 'Anna'
found_in_loop = False # Initialize flag
found_dict_loop = None

print(f"Searching for {search_key} == '{search_value}' using a loop...")
for user_dict in users:
    print(f"Checking dict: {user_dict}")
    if user_dict.get(search_key) == search_value:
        print("--> Match found!")
        found_in_loop = True
        found_dict_loop = user_dict # Store the matching dict
        break # Exit loop once found

if found_in_loop:
    print(f"Result: Value exists (first match found: {found_dict_loop}).") # This runs
else:
    print("Result: Value does not exist.")

Output:

Searching for name == 'Anna' using a loop...
Checking dict: {'id': 'u001', 'name': 'Alice', 'status': 'active'}
Checking dict: {'id': 'u002', 'name': 'Anna', 'status': 'inactive'}
--> Match found!
Result: Value exists (first match found: {'id': 'u002', 'name': 'Anna', 'status': 'inactive'}).

Getting the Index of the Matching Dictionary (enumerate)

Combine the loop with enumerate to get the index of the first match.

users = [
    {'id': 'u001', 'name': 'Alice', 'status': 'active'},
    {'id': 'u002', 'name': 'Anna', 'status': 'inactive'},
    {'id': 'u003', 'name': 'Charlie', 'status': 'active'},
]
search_key = 'name'
search_value = 'Anna'
found_index = -1 # Initialize with an invalid index

print(f"Searching for index where {search_key} == '{search_value}'...")
for index, user_dict in enumerate(users):
     if user_dict.get(search_key) == search_value:
        print(f"--> Match found at index {index}: {user_dict}")
        found_index = index
        break # Stop after finding the first match

if found_index != -1:
    print(f"Result: Value found at index {found_index}.") # Output: 1
else:
    print("Result: Value not found.")

Output:

Searching for index where name == 'Anna'...
--> Match found at index 1: {'id': 'u002', 'name': 'Anna', 'status': 'inactive'}
Result: Value found at index 1.

Method 4: Using filter() (To Get Matching Dictionaries)

If you need a list of all dictionaries that match the condition, filter() is suitable. You can then check if the resulting list is non-empty to see if any match existed.

users = [
    {'id': 'u001', 'name': 'Alice', 'status': 'active'},
    {'id': 'u002', 'name': 'Anna', 'status': 'inactive'},
    {'id': 'u003', 'name': 'Charlie', 'status': 'active'},
    {'id': 'u004', 'name': 'Anna', 'status': 'pending'}
]
search_key = 'name'
search_value = 'Anna'

matching_dicts_iterator = filter(lambda d: d.get(search_key) == search_value, users)

matching_dicts_list = list(matching_dicts_iterator)

print(f"Matching dictionaries found using filter: {matching_dicts_list}")

if matching_dicts_list: # Checks if the list is not empty
     print("--> Value exists (found via filter).") # This runs
else:
     print("--> Value does not exist (found via filter).")

Output:

Matching dictionaries found using filter: [{'id': 'u002', 'name': 'Anna', 'status': 'inactive'}, {'id': 'u004', 'name': 'Anna', 'status': 'pending'}]
--> Value exists (found via filter).

This is less direct than any() for just checking existence, but useful if you need the matching objects themselves.

Method 5: Using map() and itemgetter (Less Direct)

This approach first extracts all values for the target key and then checks if the target value is present in that extracted list. It's less efficient as it processes the whole list even if a match is found early, and less safe if keys might be missing.

from operator import itemgetter # Required import

users = [
    {'id': 'u001', 'name': 'Alice'},
    {'id': 'u002', 'name': 'Anna'},
    {'id': 'u003', 'name': 'Charlie'},
    {'id': 'u004', 'name': 'Anna'}
]
search_key = 'name'
search_value = 'Anna'

try:
    name_values_iterator = map(itemgetter(search_key), users)

    value_exists = search_value in name_values_iterator

    print(f"Values for '{search_key}': {list(map(itemgetter(search_key), users))}") # Note: consumes iterator if not listed first
    print(f"'{search_value}' exists in values (map)? {value_exists}") # Output: True

except KeyError:
    print(f"Error: Key '{search_key}' not found in all dictionaries (map method failed).")

Output:

Values for 'name': ['Alice', 'Anna', 'Charlie', 'Anna']
'Anna' exists in values (map)? True
  • itemgetter(search_key): Creates a callable to get the value for 'name'.
  • map(...): Applies the getter to each dictionary. Warning: This will raise a KeyError immediately if any dictionary in the list is missing the search_key.
  • search_value in ...: Checks if the value exists in the generated sequence of names.

This method is generally not recommended for this specific task due to its inefficiency and lack of robustness against missing keys compared to any() with .get().

If your goal is simply to get a list of all values associated with a specific key (regardless of matching a target value), a list comprehension is ideal:

users = [
    {'id': 'u001', 'name': 'Alice', 'status': 'active'},
    {'id': 'u002', 'status': 'inactive'}, # Missing 'name'
    {'id': 'u003', 'name': 'Charlie', 'status': 'active'},
]
target_key = 'name'

all_names = [user.get(target_key) for user in users]
print(f"All values for key '{target_key}': {all_names}")

all_names_filtered = [user.get(target_key) for user in users if user.get(target_key) is not None]
print(f"Filtered values for key '{target_key}': {all_names_filtered}")

Output:

All values for key 'name': ['Alice', None, 'Charlie']
Filtered values for key 'name': ['Alice', 'Charlie']

Conclusion

To check if a specific value exists for a given key in any dictionary within a list:

  • The any(d.get(key) == value for d in list_of_dicts) pattern is the most recommended method. It's concise, efficient (short-circuits), and safe against missing keys when using .get().
  • A for loop with if d.get(key) == value: ... break provides an explicit alternative. Use enumerate if you need the index of the first match.
  • Use filter() or list comprehensions if you need to retrieve the actual dictionary(ies) that match, not just check for existence.

Choose the method that best suits your specific need – simple existence check (any), retrieving the first match (any with := or loop with break), or retrieving all matches (filter/list comprehension). Always prefer .get() over direct indexing ([]) for safety when keys might be missing.

Navigation