Skip to main content

How to Find and Filtering Objects in Lists in Python

Efficiently searching and filtering collections of custom objects is essential for writing clean and performant Python code.

This guide explores various methods for achieving this, including:

  • Finding the first object that meets a condition
  • Checking if at least one object meets a condition
  • Returning all the objects that meet a condition, using either list comprehensions, or the filter() function.

Finding the First Matching Object with next()

To find the first object in a list that satisfies a given condition, use a generator expression in combination with the next() function:

class Employee():
def __init__(self, name, salary):
self.name = name
self.salary = salary

def __repr__(self):
return self.name

alice = Employee('Alice', 100)
anna = Employee('Anna', 75)
carl = Employee('Carl', 75)

employees = [alice, anna, carl]

result = next(
(emp for emp in employees if emp.name == 'Anna'),
None
)

print(result) # Output: Anna

if result: # Check that the result is not None
print(result.name) # Output: Anna
print(result.salary) # Output: 75
  • The generator expression (emp for emp in employees if emp.name == 'Anna') filters through the employees list.
  • The next() function returns the first object that satisfies the condition, and the None second parameter serves as a default value which will be returned if no objects match the condition.
  • You should always perform a check if result before accessing properties on the object because the object can be None.

Checking if an Object Exists with any()

Use the any() function to check if a list contains at least one matching object:

class Employee():
def __init__(self, name, salary):
self.name = name
self.salary = salary

def __repr__(self):
return self.name

alice = Employee('Alice', 100)
anna = Employee('Anna', 75)
carl = Employee('Carl', 75)

employees = [alice, anna, carl]

if any(emp.salary > 130 for emp in employees):
print('One or more objects meet the condition')
else:
print('None of the objects meet the condition') # Output: None of the objects meet the condition
  • The any() function will return True if at least one object satisfies the salary > 130 condition.

Finding All Matching Objects with List Comprehensions

To retrieve all objects in a list that meet a specific condition, list comprehensions provide a concise and efficient method:

class Employee():
def __init__(self, name, salary):
self.name = name
self.salary = salary

def __repr__(self):
return self.name

alice = Employee('Alice', 100)
anna = Employee('Anna', 75)
carl = Employee('Carl', 75)

employees = [alice, anna, carl]

matches = [emp for emp in employees if emp.salary == 75]
print(matches) # Output: [Anna, Carl]
  • The list comprehension [emp for emp in employees if emp.salary == 75] will iterate over the list and return only the Employee objects where salary equals 75.

Returning Specific Attributes

You can modify list comprehensions to return only the values of a specific attribute of the matching objects:

class Employee():
def __init__(self, name, salary):
self.name = name
self.salary = salary

def __repr__(self):
return self.name

alice = Employee('Alice', 100)
anna = Employee('Anna', 75)
carl = Employee('Carl', 150)

employees = [alice, anna, carl]

filtered_names = [emp.name for emp in employees if emp.salary > 80]
print(filtered_names) # Output: ['Alice', 'Carl']
  • The list comprehension [emp.name for emp in employees if emp.salary > 80] will create a list containing the name attribute of every Employee in the employees list where salary is greater than 80.

Finding All Matching Objects with a for Loop

A for loop can also be used to create a list of all matching objects:

class Employee():
def __init__(self, name, salary):
self.name = name
self.salary = salary

def __repr__(self):
return self.name

alice = Employee('Alice', 100)
anna = Employee('Anna', 75)
carl = Employee('Carl', 75)

employees = [alice, anna, carl]

matches = []
for emp in employees:
if emp.salary == 75:
matches.append(emp)
print(matches) # Output: [Anna, Carl]
  • The loop will iterate through all items and add the matching objects to the matches list.

Filtering Lists of Objects with the filter() Function

The filter() function provides an alternative way to filter a list based on a condition:

class Employee():
def __init__(self, name, salary):
self.name = name
self.salary = salary

def __repr__(self):
return self.name

alice = Employee('Alice', 100)
anna = Employee('Anna', 75)
carl = Employee('Carl', 150)

employees = [alice, anna, carl]

filtered_list = list(filter(lambda emp: emp.salary > 80, employees))

print(filtered_list) # Output: [Alice, Carl]
print(filtered_list[0].name) # Output: Alice
print(filtered_list[0].salary) # Output: 100
  • The filter() function will return a filter object (an iterator) which elements satisfy the condition given by the lambda function. The list() will then transform that into a list.