У меня есть два списка объектов, и мне нужно найти подходящие объекты в соответствии с двумя различными наборами атрибутов.Скажем, у меня есть объекты Vehicle (), и мне нужно сначала сопоставить все транспортные средства из первого списка, которые совпадают с транспортными средствами во втором, сначала посмотреть на соответствующие цвета, а затем на соответствующие бренды.У меня есть два решения, но я не уверен, что это лучшее, что я могу сделать.(Мне действительно нужно оптимизировать эту производительность)
Итак, скажем, у меня есть:
class Vehicle(object):
def __init__(self, color, brand):
self._color = color
self._brand = brand
и списки объектов как таковые:
vehicles1= [Vehicle('blue','fiat'), Vehicle('red','volvo'), Vehicle('red','fiat')]
vehicles2 = [Vehicle('blue', 'volvo'), Vehicle('red', 'BMW')]
Первое решение, который кажется невероятно медленным, должен работать только с включением в список:
inersect_brand_wise = [x for x in vehicles1 for y in vehicles2 if x._brand == y._brand]
затем
intersect_color_wise = [x for x in vehicles1 for y in vehicles2 if x._color == y._color]
Второе решение, которое я нашел, состоит в разработке равенства:
class Vehicle(object):
def __init__(self, color, brand):
self._color = color
self._brand = brand
def __eq__(self, other):
if isinstance(other, Vehicle):
return self._brand == other._brand
return False
def __hash__(self):
return hash((self._color, self._brand))
Теперь получить пересечение по марке тривиально:
inersect_brand_wise = [x for x in vehicles1 if x in vehicles2]
Чтобы получить пересечение по цвету, я сделал следующее:
class Car(Vehicle):
def __init__(self, color, brand):
Vehicle.__init__(self,color, brand)
def __hash__(self):
return Vehicle.__hash__
def __eq__(self, other):
if isinstance(other, Car):
return other._color == self._color
return False
def change_to_car(obj):
obj.__class__ = Car
return obj
cars1 = map(change_to_car, vehicles1)
cars2 = map(change_to_car, vehicles2)
И, таким образом,
intersect_color_wise = [x for x in cars1 if x in cars2]
дает второе пересечение.
Однако, мне кажется, что это очень неуклюжий способ сделать что-то, и я действительно нуждаюсь в хорошей производительности на этом.
Любые предложенияо том, как сделать лучше, чем все это?
Заранее спасибо, M