I have two lists of class objects in Python (both are the same type), and when comparing them, I need to identify objects that exists in both lists by comparing them using a function that returns True
or False
.
I need to compare a car's tires to determine if the tire is a match ("it'll fit"), and sometimes if a tire is identical (same brand/make/year).
Given the example below, how can I compare the car's current tires to a list of potential tires I got back from the previous
find
call using thecompare.is_exact_match
function?
I've seen similar questions like this one which lets me compare objects based on the value of a property, but I'm not sure if (how) this same method could work for a function comparison.
I have a Car
, and one of its properties is a set of tires (subclass Tire
):
def Car:
def __init__(self, ...args):
self.make = make
self.model = model
self.year = year
self.trim = trim
self.color = color
self.vin = vin
self.tires: [Tire] = tires
self.potential_matches: [Tire] = []
def Tire:
def __init__(self, ...args):
self.brand = brand
self.model_number = model_number
self.year = year
self.diameter = diameter
self.width = width
self.sidewall = sidewall
self.circumference = self.circumference
self.revs_per_mile = self.revs_per_mile
I have some a somewhat complicated heuristic that compares lists of cars to find matching tires for this car. This is a mock example, but let's assume this is a tire swapping marketplace so you understand how we go there. In this theoretical product, tire data in the marketplace is often incomplete. Determining if a tire is a match is expensive, so we do some prework to reduce that footprint. Once we have that, we often need to further compare tires to differentiate between "just a match" and "an identical tire".
This looks something like:
@classmethod
def find(cls, car: Car, marketplace_cars: [Car]) -> [Car.Tire]:
matches = list(filter(lambda c:
# One thing we can try is comparing the car first. If the car is a match,
# the tires probably are too.
car.make == c.make
and car.model == c.model
and car.year == c.year
and car.trim == c.trim
# If any of those fail, run the expensive heuristic
and compare.is_match(car, c)
marketplace_cars))
# Extract a list of tires from the list of cars that were identified as having matches
matching_tires = list(itertools.chain(*[m.tires for m in matches]))
return matching_tires
Now from this list, we want to further narrow it down to show any tires that are identical matches. This means comparing make, model, and mileage as well as all the other stuff in the first comparison. The compare.is_exact_match
takes individual Tire
objects this time and compares them.
And this is where I'm lost:
How can I compare the car's current tires to a list of potential tires I got back from the previous
find
call using thecompare.is_exact_match
function?
@classmethod
def find_exact(cls, car: Car) -> [Car.Tire]:
# Pseudo code, because what do I do here?
# Should/can I do this with sets, or?
exact_matches = list(filter(
lambda tire, match: compare.is_exact_match(tire, match),
(car.tires, car.potential_matches)))
# Returns an array of [Car.Tire] that are exact matches
return exact_matches
It turns out I was really overthinking this, and a simple list comprehension was all I needed.
@classmethod
def find_exact(cls, car: Car) -> [Car.Tire]:
exact_matches = [m for t in car.tires for m in car.potential_matches if compare.is_exact_match(t, m)]
"""
for t in car.tires:
for m in car.potential_matches:
if compare.is_exact_match(t, m):
m
"""
# Returns an array of [Car.Tire] that are exact matches
return exact_matches