Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Identify the elements which are removed from set() in python?

I tried using set() method of python to find the unique elements in the List. It works fine removing all the duplicates. But here is my requirement, I want to get the elements which are removed by using set() method. Could any one please assist me in this?

a=[1,2,3,1,4]
b=set(a)
Output:[1,2,3,4]

My expected output is [1].The element which is removed from the set() method

like image 212
Gokul Krishna Avatar asked Mar 25 '15 07:03

Gokul Krishna


5 Answers

You don't even need set. You want a count of each element with more than one occurrence. Counter from collections together with a dictionary comprehension should get you there.

from collections import Counter

a = [1, 1, 1, 2, 2, 3, 4]    
removed = {k: v-1 for k, v in Counter(a).iteritems() if v > 1}

>>> removed
Out[8]: {1: 2, 2: 1}
like image 190
Alexander Avatar answered Nov 10 '22 21:11

Alexander


collections.Counter is useful here.

from collections import Counter
counts = Counter(a)
b = set(counts.keys())
for x, count in counts.items():
    if count > 1:
        print('%d appearances of %s were removed in the set' % (count-1, x))
like image 27
shx2 Avatar answered Nov 10 '22 21:11

shx2


Try this with Counter

from collections import Counter
a = [1, 2, 3, 1, 4]
>>>[i for i in Counter(a) if Counter(a)[i] > 1]
[1]
like image 24
itzMEonTV Avatar answered Nov 10 '22 20:11

itzMEonTV


You can extend Set class(have your own Set class say MySet) and override this function

def _update(self, iterable):
    # The main loop for update() and the subclass __init__() methods.
    data = self._data

    # Use the fast update() method when a dictionary is available.
    if isinstance(iterable, BaseSet):
        data.update(iterable._data)
        return

    value = True

    if type(iterable) in (list, tuple, xrange):
        # Optimized: we know that __iter__() and next() can't
        # raise TypeError, so we can move 'try:' out of the loop.
        it = iter(iterable)
        while True:
            try:
                for element in it:
                    data[element] = value
                return
            except TypeError:
                transform = getattr(element, "__as_immutable__", None)
                if transform is None:
                    raise # re-raise the TypeError exception we caught
                data[transform()] = value
    else:
        # Safe: only catch TypeError where intended
        for element in iterable:
            try:
                data[element] = value
            except TypeError:
                transform = getattr(element, "__as_immutable__", None)
                if transform is None:
                    raise # re-raise the TypeError exception we caught
                data[transform()] = value
like image 45
Syed Mauze Rehan Avatar answered Nov 10 '22 20:11

Syed Mauze Rehan


I think you're approaching the problem in a slightly conflated way. Rather than trying to get a set() to do something it's not intended to do (return a list of duplicates) I would use a collections.Counter() to gather up the duplicates and then get the set from that.

Here's some code:

#!python
from collections import Counter
c = Counter([1,2,3,1,4])
dupes = [k for k,v in c.items() if v>1]
b = set(c.keys())
like image 31
Jim Dennis Avatar answered Nov 10 '22 21:11

Jim Dennis