Python Forum
How to check if class instance exists in a list of class instance objects?
Thread Rating:
  • 1 Vote(s) - 1 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to check if class instance exists in a list of class instance objects?
#1
Hi,

I have a list of class instances:

mylist = [ myClass(name=n1), myClass(name=n2), myClass(name=n1), myClass(name=n3) ]
How can I get rid of duplicates in this list?
I know that the two instances with the name='n1' are in reality 2 different objects, so they are in reality not duplicates.
But for my project, having several instances with the same parameters means basically duplicates and I need to clean up the list accordingly.

Is there any easy way to do it?

Thanks.
Reply
#2
Hello, found possible solution for you here: https://stackoverflow.com/questions/2461...-attribute
Reply
#3
You need to implement some special methods in your class. Here is a quick example

class Person():
    def __init__(self, name):
        self.name = name
        
    def __eq__(self, other):
        return (self.name, ) == (other.name, )
        
    def __hash__(self):
        return hash((self.name,))
        
    def __str__(self):
        return self.name
        

    
person1 = Person('John')
person2 = Person('Allice')
person3 = Person('John')

persons = [person1, person2, person3]
print(persons)
for person in persons:
    print(person)

unique_persons = set(persons)
print(unique_persons)
for person in unique_persons:
    print(person)
Output:
[<__main__.Person instance at 0x02FB1B20>, <__main__.Person instance at 0x02FB53F0>, <__main__.Person instance at 0x02FB5418>] John Allice John set([<__main__.Person instance at 0x02FB1B20>, <__main__.Person instance at 0x02FB53F0>]) John Allice >>>
note that I have added __str__() just for more clarity in the example output
if for some reason you don't want/are not able to change the class

class Person():
    def __init__(self, name):
        self.name = name
         
    def __str__(self):
        return self.name
     
person1 = Person('John')
person2 = Person('Allice')
person3 = Person('John')
 
persons = [person1, person2, person3]
print(persons)
for person in persons:
    print(person)
 
def dedup(persons):
    unique = []
    unique_names = set()
    for person in persons:
        if person.name not in unique_names:
            unique.append(person)
            unique_names.add(person.name)
    return unique
    
unique_persons = dedup(persons)
print(unique_persons)
for person in unique_persons:
    print(person)
Output:
[<__main__.Person instance at 0x02FD1E40>, <__main__.Person instance at 0x02FD53A0>, <__main__.Person instance at 0x02FD53C8>] John Allice John [<__main__.Person instance at 0x02FD1E40>, <__main__.Person instance at 0x02FD53A0>] John Allice >>>
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#4
What is the basis in order to compare classes? The __hash__ method?
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#5
(May-25-2018, 12:23 PM)wavic Wrote: What is the basis in order to compare classes?
no, comparison special methods - https://rszalski.github.io/magicmethods/#comparisons
__hash__() is to make it hashable. In this example case without it you will not be able to put instance of the class in a set.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#6
As I see it, what will be compared depends on me?
Btw, the link is great!
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#7
Thank you all.
For my script, these methods are an overkill, but it's good to know the approach and that there is no magic trick to do it easily.
I will do it the way Buran suggested when I am not able to change the class definition. Basically create a separate list of unique values of instance names.
Reply
#8
(May-25-2018, 01:50 PM)sonicblind Wrote: I will do it the way Buran suggested when I am not able to change the class definition. Basically create a separate list of unique values of instance names.
Thinking some more on it, you can do like this
class Person():
    def __init__(self, name):
        self.name = name
          
    def __str__(self):
        return self.name
      
person1 = Person('John')
person2 = Person('Allice')
person3 = Person('John')
  
persons = [person1, person2, person3]
print(persons)
for person in persons:
    print(person)
  
    
unique_persons = {person.name:person for person in persons}.values()
print(unique_persons)
for person in unique_persons:
    print(person)
Output:
[<__main__.Person instance at 0x030A4A58>, <__main__.Person instance at 0x03121B20>, <__main__.Person instance at 0x03121E40>] John Allice John [<__main__.Person instance at 0x03121E40>, <__main__.Person instance at 0x03121B20>] John Allice >>>
Making a dictionary and then taking the list of values(instances of the class). In this case it will keep the last one with the same name, while in the other example it will keep the first instance with given name. If you want to use a multi-attribute key, then use a tuple of these atributes as key.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#9
A example with set comprehension.
>>> persons = [person1, person2, person3]
>>> unique_persons = {person.name for person in persons}
>>> unique_persons
{'Allice', 'John'}
If need to keep order buran dictionary(3.6+) will do that.
Just need a unique person list,set comprehension is good.
Reply
#10
(May-25-2018, 06:09 PM)snippsat Wrote: Just need a unique person list,set comprehension is good.
just a small note - that's unique person names list set, but OP wants unique list of instances
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  class and runtime akbarza 4 209 Mar-16-2024, 01:32 PM
Last Post: deanhystad
  Help with to check an Input list data with a data read from an external source sacharyya 3 295 Mar-09-2024, 12:33 PM
Last Post: Pedroski55
  Operation result class SirDonkey 6 393 Feb-25-2024, 10:53 AM
Last Post: Gribouillis
  The function of double underscore back and front in a class function name? Pedroski55 9 526 Feb-19-2024, 03:51 PM
Last Post: deanhystad
  super() and order of running method in class inheritance akbarza 7 580 Feb-04-2024, 09:35 AM
Last Post: Gribouillis
  Class test : good way to split methods into several files paul18fr 4 380 Jan-30-2024, 11:46 AM
Last Post: Pedroski55
  Good class design - with a Snake game as an example bear 1 1,703 Jan-24-2024, 08:36 AM
Last Post: annakenna
  question about __repr__ in a class akbarza 4 504 Jan-12-2024, 11:22 AM
Last Post: DeaD_EyE
  [solved] list content check paul18fr 6 589 Jan-04-2024, 11:32 AM
Last Post: deanhystad
  error in class: TypeError: 'str' object is not callable akbarza 2 418 Dec-30-2023, 04:35 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020