3

I have a Set which stores IP addresses. The IP address could be a unique IP or a subnet. I have overloaded the __hash__ and __eq__ methods. The Set works fine.

Question is : When I am trying to add a duplicate element, is there a way to show the original element?

I cannot use the in operation because it will take a long time since there are about 100,000 IP addresses and I could create only like 5 different buckets for the Set.

An example

I added the subnet 10.0.0.0/8 to the Set.

I then tried to add the unique IP 10.10.10.10 to the Set.

The Set won't add the unique IP because it is a duplicate of the subset 10.0.0.0/8. At such a situation I want to show the user:

10.10.10.10 duplicate of 10.0.0.0/8

P.S : I just went through the definition of in operation. It just shows if the element is already present or not. It won't show the original element. (I am not a python developer).

P.P.S : I am reading a firewall ACL list. I am adding lot more than just add IP address to the set. That is why I can't show the code here. The code works.

Edouard Thiel
  • 5,878
  • 25
  • 33
Jitin Kodian
  • 471
  • 4
  • 14

1 Answers1

1

You could look at the intersection of the IP address set and a new set containing just the item you want to add to the set.

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)}

In the case of a new item not being in the set you will do two lookups.

Edit: Intersection will always return the member of the smaller set see here. Therefore you could use this method instead:

def isolate(new_item, existing_set):
    for item in existing_set:
        if item == new_item:
            return item
Community
  • 1
  • 1
Henry Heath
  • 1,072
  • 11
  • 19
  • Great Idea. I never thought of using intersection. I don't have time to check this code now. I will try it out after weekend and if it works I will accept your answer. I have upvoted your answer. – Jitin Kodian Dec 09 '16 at 11:30
  • My doubt is : will `intersection` have the element from `existing_set` or from `new_item`? Even though both are same according to my `eq` method, the values in both the elements will be different. I want `intersection` to have the element from `existing_set` – Jitin Kodian Dec 09 '16 at 11:32
  • You're right - the intersection always returns the item from the smaller set: http://stackoverflow.com/questions/20100003/whats-the-algorithm-of-set-intersection-in-python – Henry Heath Dec 09 '16 at 12:19
  • I don't want values from the smaller set and I don't want to use `in` because it will take a long time. I will come up with a different logic. I will accept your answer as you told me there is no good way for me to get the original element – Jitin Kodian Dec 14 '16 at 04:56