Python与自定义对象

时间:2018-03-04 12:08:17

标签: python data-structures set

我有两组自定义对象,我使用以下词典元组构建:

tupleOfDicts1 = ({'id': 1, 'name': 'peter', 'last': 'smith'},
                 {'id': 2, 'name': 'peter', 'last': 'smith'},
                 {'id': 3, 'name': 'mark', 'last':'white'},
                 {'id': 4, 'name': 'john', 'last': 'lennon'},)

tupleOfDicts2 = ({'id': 9, 'name': 'peter', 'last': 'smith'},
                 {'id': 8, 'name': 'peter', 'last': 'smith'},)

正如您所看到的,除了'id'属性之外,我有相同的元素。

然后我定义了以下对象:

class Result:    
    def __init__(self, **kwargs):
        self.id = kwargs['id']
        self.nome = kwargs['name']
        self.cognome = kwargs['last']

    def __repr__(self):
        return 'Result(%s, %s, %s)' %(self.id, self.name, self.last)

    def __hash__(self):
        #  hash must consider the id of the elements, but the id must not be considered when comparison
        return hash((self.id, self.name, self.last))

    def __eq__(self, other):
        if isinstance(other, Result):
            #  I want comparison to be made considering only name and last
            return (self.name, self.last) == (other.name, other.last)
        else:
            return False

    def __ne__(self, other):
        return not self.__eq__(other)

如您所见,此对象已准备好接收构造函数中的词典。

现在我定义一个函数,该函数从包含字典的元组返回一组Result对象:

def getSetFromTuple(tupleOfDicts):
    myset = set()
    for dictionary in tupleOfDicts:
        myset.add(Result(**dictionary))
    return myset

此时我创建了两套:

mySet1 = getSetFromTuple(tupleOfDicts1)
mySet2 = getSetFromTuple(tupleOfDicts2)

我做了所有这些因为我想在mySet1上拥有mySet2上没有的所有元素(为了这个比较,我不希望属性'id'参与其中):

diff = mySet1 - mySet2

但我没有得到我想要的东西,在这种情况下,我得到了mySet1的所有元素:

print(len(mySet1 - mySet2))  # 4

我希望mySet1只剩下两个元素,因为它的两个元素在mySet2上(具有相同的name和相同的last id将始终不同。)< / p>

在我看来,当我在两个集合之间调用-运算符时,此类将比较元素的哈希值。在这种情况下,4的输出是有意义的。但是:有办法做我想做的事吗?

1 个答案:

答案 0 :(得分:2)

与您的评论相反,我认为id不应该在哈希中。如果两个元素相等,则它们的哈希值必须相等:

def __hash__(self):
  return hash((self.name, self.last))

内部hash将值映射到存储桶。具有不同散列的元素可能最终存在于不同的存储桶中,并且避免在重复数据删除(设置)/查询(字典)时进行完全比较。

也就是说,有一种更简单的方法可以获得结果,而不涉及OOP并只使用数据本身:

dictionaries = tupleOfDicts1 + tupleOfDicts2
unique_values = {(d['name'], d['last']): d for d in dictionaries}.values()