I've got a list of objects and I've got a db table full of records. My list of objects has a title attribute and I want to remove any objects with duplicate titles from the list (leaving the original).
Then I want to check if my list of objects has any duplicates of any records in the database and if so, remove those items from list before adding them to the database.
I have seen solutions for removing duplicates from a list like this: myList = list(set(myList))
, but i'm not sure how to do that with a list of objects?
I need to maintain the order of my list of objects too. I was also thinking maybe I could use difflib
to check for differences in the titles.
The
set(list_of_objects)
will only remove the duplicates if you know what a duplicate is, that is, you'll need to define a uniqueness of an object.In order to do that, you'll need to make the object hashable. You need to define both
__hash__
and__eq__
method, here is how:http://docs.python.org/glossary.html#term-hashable
Though, you'll probably only need to define
__eq__
method.EDIT: How to implement the
__eq__
method:You'll need to know, as I mentioned, the uniqueness definition of your object. Supposed we have a Book with attributes author_name and title that their combination is unique, (so, we can have many books Stephen King authored, and many books named The Shining, but only one book named The Shining by Stephen King), then the implementation is as follows:
Similarly, this is how I sometimes implement the
__hash__
method:You can check that if you create a list of 2 books with same author and title, the book objects will
be the same (withequal (withis
operator) and==
operator). Also, whenset()
is used, it will remove one book.EDIT: This is one old anwser of mine, but I only now notice that it has the error which is corrected with strikethrough in the last paragraph: objects with the same
hash()
won't giveTrue
when compared withis
. Hashability of object is used, however, if you intend to use them as elements of set, or as keys in dictionary.If you want to preserve the original order use it:
If you don't care of ordering then use it:
Its quite easy freinds :-
thats it ! :)
This seems pretty minimal:
Both
__hash__
and__eq__
are needed for this.__hash__
is needed to add an object to a set, since python's sets are implemented as hashtables. By default, immutable objects like numbers, strings, and tuples are hashable.However, hash collisions (two distinct objects hashing to the same value) are inevitable, due to the pigeonhole principle. So, two objects cannot be distinguished only using their hash, and the user must specify their own
__eq__
function. Thus, the actual hash function the user provides is not crucial, though it is best to try to avoid hash collisions for performance (see What's a correct and good way to implement __hash__()?).I recently ended up using the code below. It is similar to other answers as it iterates over the list and records what it is seeing and then removes any item that it has already seen but it doesn't create a duplicate list, instead it just deletes the item from original list.