gpt4 book ai didi

python - 检查具有不同属性的对象是否相等

转载 作者:行者123 更新时间:2023-11-28 18:59:25 26 4
gpt4 key购买 nike

我有两个对象列表,我需要根据两组不同的属性找到匹配的对象。比方说,我有 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]

给出第二个路口。

但是,在我看来,这是一种非常笨拙的做事方式,实际上我需要在这方面有良好的表现。

关于如何做得更好,有什么建议吗?

提前致谢,米

最佳答案

这种情况下的表现如何?没有完整的数据集来模拟正确测试的性能......:

def get_intersections(list1, list2):
brands, colors = map(set, zip(*[(v._brand, v._color) for v in list2]))
inter_brands = [v for v in list1 if v._brand in brands]
inter_colors = [v for v in list1 if v._colors in colors]
return inter_brands, inter_colors

如果需要,您也可以编写单独的交叉点:

from operator import attrgetter

def get_intersection(list1, list2, attr:str):
getter = attrgetter(attr)
t_set = {getter(v) for v in list2}
results = [v for v in list1 if getter(v) in t_set]
return results

# use it like this:
get_intersection(vehicles1, vehicles2, "_brand")

您还可以使用 attrgetter 缩放第一个函数以获得任意数量的属性:

def get_intersections(list1, list2, *attrs:str):
getter = attrgetter(*attrs)
if len(attrs) > 1:
sets = list(map(set, zip(*[getter(v) for v in list2])))
else:
sets = [{getter(v) for v in list2}]
results = {attr: [v for v in vehicles1 if getattr(v, attr) in sets[s]] for s, attr in enumerate(attrs)}
return results

测试:

>>> get_intersections(vehicles1, vehicles2, "_brand", "_color")

{'_brand': [<__main__.Vehicle object at 0x03588910>], '_color': [<__main__.Vehicle object at 0x035889D0>, <__main__.Vehicle object at 0x03588910>, <__main__.Vehicle object at 0x035889F0>]}

>>> get_intersections(vehicles1, vehicles2, "_brand")

{'_brand': [<__main__.Vehicle object at 0x03588910>]}

关于python - 检查具有不同属性的对象是否相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54482707/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com