Monday, November 7, 2022

[FIXED] How to get list of objects with unique attribute

Issue

Background

I have a list. This list has many objects. Each object has an id. Now the objects are of different types.

objects = [Aobject, Bobject, Cobject]

where

>>> Aobject != Bobject
True
>>> Aobject.id ==  Bobject.id
True

Problem

I want a list of unique objects based on the object.id.

Something like this:

set(objects, key=operator.attrgetter('id'))

(This does not work. But I want something like this)


Solution

seen = set() 

# never use list as a variable name
[seen.add(obj.id) or obj for obj in mylist if obj.id not in seen]

This works because set.add returns None, so the expression in the list comprehension always yields obj, but only if obj.id has not already been added to seen.

(The expression could only evaluate to None if obj is None; in that case, obj.id would raise an exception. In case mylist contains None values, change the test to if obj and (obj.id not in seen))

Note that this will give you the first object in the list which has a given id. @Abhijit's answer will give you the last such object.

Update:

Alternatively, an ordereddict could be a good choice:

import collections
seen = collections.OrderedDict()

for obj in mylist:
    # eliminate this check if you want the last item
    if obj.id not in seen:
       seen[obj.id] = obj

list(seen.values())


Answered By - Marcin
Answer Checked By - Robin (PHPFixing Admin)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.