Select from a list of objects where a value occurs more than once

Question:

I have a list of the below custom object in python. I want to create a new list of objects where the ‘ledId’ more than once (like a list of duplicates based on an id)

The object

class CustomObject:
    def __init__(self, id, ledId):
        self.id = id
        self.ledId = ledId

I usually use C# so I am wanting to do something like

var subList = myList.Where(obj => myList.Count(l => l.ledId == obj.ledId) > 1)
                     .ToList();

Is there an easy way to do this in python?

Asked By: primmslim

||

Answers:

Rewriting you code in C# to Python would be something like this:

[a for a in some_list if len([b for b in some_list if b.ledId == a.ledId]) > 1]
Answered By: maciek97x
my_list = [
    CustomObject(1, 10),
    CustomObject(2, 20),
    CustomObject(3, 10),
    CustomObject(4, 30),
    CustomObject(5, 10)
]

duplicates = [obj for obj in my_list if len(list(filter(lambda x: x.ledId == obj.ledId, my_list))) > 1]
Answered By: Akash Shetty

The other solutions will work, but for the record, the algorithm as presented here is in O(n^2), since you run the count for each iteration. You can make it O(n) by counting once, and storing the result in a dict:

from collections import defaultdict

counts = defaultdict(int)

for custom_object in sub_list:
    counts[custom_objects.ledId] += 1

result = [x for x in sub_list if counts[x.ledId] > 1]

It is also a great opportunity to use defaultdict, but you do lose the very functional approach from C#, to make it more "Pythonic".

Answered By: Florent Monin
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.