添加重复时从集合中获取原始元素

时间:2016-12-09 09:34:24

标签: python set

我有Set存储IP地址。 IP地址可以是唯一的IP或子网。我重载了__hash____eq__方法。 Set工作正常。

问题是:当我尝试添加重复元素时,有没有办法显示原始元素?

我无法使用in操作,因为它需要很长时间,因为大约有100,000个IP地址,我只能为Set创建5个不同的存储桶。

示例

我将子网10.0.0.0/8添加到Set

然后我尝试将唯一的IP 10.10.10.10添加到Set

Set不会添加唯一的IP,因为它是子集10.0.0.0/8的副本。在这种情况下,我想向用户显示:

  

10.10.10.10 10.0.0.0/8的副本

P.S:我刚刚完成了in操作的定义。它只显示元素是否已存在。它不会显示原始元素。 (我不是python开发人员)。

P.P.S:我正在阅读防火墙ACL列表。我添加的不只是添加IP地址到集合。这就是我无法在此处显示代码的原因。代码有效。

1 个答案:

答案 0 :(得分:1)

您可以查看IP地址集与仅包含要添加到集合中的项目的新集合的交集。

class MyClass:

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return 'MyClass({})'.format(self.name)

    def __eq__(self, other):
        return isinstance(other, MyClass)

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

    def __hash__(self):
        return 0

existing_set = {MyClass('existing')}
new_item = MyClass('new')
intersection = {new_item}.intersection(existing_set)

if intersection:
    print('{} duplicate of {}'.format(new_item, intersection.pop()))
    # MyClass(new) duplicate of MyClass(existing)
else:
    existing_set.add(new_item)
print(existing_set)
# {MyClass(existing)}

如果新项目不在集合中,您将进行两次查找。

编辑:交叉将始终返回较小集的成员,请参阅here。因此,您可以使用此方法:

def isolate(new_item, existing_set):
    for item in existing_set:
        if item == new_item:
            return item