0

I have a dictionary with a list of objects as values like:

{"A": [obj1, obj2, obj3], "B": [obj1, obj4, obj5]}

Here, I'd like to get a list of unique objects such as

[obj1, obj2, obj3, obj4, obj5]

These objects do not have as single unique attribute (for ex. a unique id).

I tried using set() but since the objects aren't hashable I haven't had success.

How can I accomplish this task?

  • 1
    Please repeat [on topic](https://stackoverflow.com/help/on-topic) and [how to ask](https://stackoverflow.com/help/how-to-ask) from the [intro tour](https://stackoverflow.com/tour). “Show me how to solve this coding problem” is not a Stack Overflow issue. We expect you to make an honest attempt, and *then* ask a *specific* question about your algorithm or technique. You have two steps: gather all of the dict values, and de-duplicate that list. Each step is documented quite well; use your browser search. – Prune Oct 20 '20 at 20:29
  • are the objects hashable? – James Oct 20 '20 at 20:29
  • They aren't @James. Added appropriate edit. –  Oct 20 '20 at 20:31
  • @Prune Updated the question with some more info. –  Oct 20 '20 at 20:31
  • 1
    Declare a master empty list. Iterate over each list in the dict. If the current object is not in the master list, add it. – John Gordon Oct 20 '20 at 20:33
  • 3
    First, you have to define what makes object equal. Then, the rest get easier – rafaelc Oct 20 '20 at 20:36

3 Answers3

1

Assuming your dictionary is m you can use a set like this:

s = set()
m = {'a': [1,2,3], 'b': [2,3,4,5,6]}
for v in m.values():
    t_set = set(v)
    s.update(t_set)

s
{1, 2, 3, 4, 5, 6}

I see you say your objects are not hashable. If they are objects you have created, you can override the __hash__() function and define your own way to make them hashable.

Chrispresso
  • 3,660
  • 2
  • 19
  • 31
0

You can use itertools.chain to make an iterator over all the values. Then a simple trick using dict.fromkeys instead of a set to retain order while only keeping unique values. (Keep in mind that the objects must be indexable/hashable) You will need to figure out how these objects are comparable in order to accomplish this task at all.

from itertools import chain

data = {"A": [obj1, obj2, obj3], "B": [obj1, obj4, obj5]}

output = list(dict.fromkeys(chain(*data.values())))

[obj1, obj2, obj3, obj4, obj5]
Jab
  • 26,853
  • 21
  • 75
  • 114
-1

The following works.

def get_unique_objs(data):
    ret = []
    for obj_list in data.values():
        for obj in obj_list:
            if obj not in ret:
                ret.append(obj)
    return ret

This will return you a list where no two objects are equal according to the objects' __eq__ magic methods if available and/or a comparison with the is operator (which is implemented by the Python interpreter and is always available and cannot be overriden).

In some circumstances there might be a little bit more coming into play as well. This shows the complete process of checking if an object should be added to the resulting list.

hostingutilities.com
  • 8,894
  • 3
  • 41
  • 51