我正在尝试为问题实施基于集合的解决方案,并且遇到了一些问题。
问题是:我有两组Group
个对象。这些集在email
上应该是唯一的(因此我们可以检查一个集合中的对象是否为in
另一个集合。)
但是,如果两个Group
对象只有电子邮件匹配,则它们不是__eq__()
(例如,一个集合可能包含具有新Group
的更新description
对象})。我的目标是设置一个集合,我只能根据email
字段执行集合操作(交集和差异)...然后根据其他字段(description
和name
检查相等性)
class Group:
def __init__(self, name, email, description):
self.name = name
self.email = email
self.description = description
def __hash__(self):
return hash(self.email)
def __eq__(self, other):
return self.email == other.email
and self.description == other.description
and self.name == other.name
def __ne__(self, other):
return not self.__eq__(other)
def __str__(self):
return "Description: {0} Email: {1} Name: {2}".format(self.description, self.email, self.name)
所以我希望所有的断言声明都能在这里传递:
group_1 = Group('first test group', 'testing@example.com', 'example description')
group_2 = Group('second test group', 'real@example.com', 'example description')
group_3 = Group('third group', 'testing@example.com', 'example description')
group_5 = Group('updated name', 'testing@example.com', 'example description')
group_set = set([group_1, group_2, group_3])
group_set_2 = set([group_3, group_5])
self.assertTrue(group_5 in group_set.intersection(group_set_2))
self.assertEqual(2, len(group_set))
self.assertTrue(group_5 in group_set)
答案 0 :(得分:1)
Python的set
类型使用对象的__eq__
方法实现的相等性测试来确定对象是否与其内容中的另一个对象“相同”。 __hash__
方法仅允许它更有效地查找要比较的其他元素。因此,您希望基于与__hash__
方法不同的属性集使用__eq__
方法是行不通的。具有相同__hash__
值的多个不等对象可以存在于同一set
中(尽管由于哈希冲突,set
的效率会稍低)。
如果您想要从电子邮件地址到Group
的唯一映射,我建议使用字典,其中键是电子邮件地址,值是Group
个对象。这样可以确保电子邮件地址是唯一的,同时还可以让您以最合适的方式比较Group
个对象。
要在两个这样的词典之间执行联合,请在一个词典的副本上使用update
方法:
union = dict_1.copy()
union.update(dict_2)
对于十字路口,请使用字典理解:
intersection = {email: group for email, group in dict_2.iteritems() if email in dict_1}
这两项操作都会优先考虑dict_2
的值,而不是dict_1
的值,只要同一封电子邮件出现在同一个电子邮件中,两者都是关键。如果您希望它以其他方式工作,只需切换字典名称。