11

I have a nested list which contains different objects, they're duplicate pairs of objects in the nested list and i'm trying to remove them but i keep getting a

TypeError: unorderable types: practice() < practice()

I know this error is caused by me trying to work with objects rather than integers but i don't know how else to remove the duplicates here is what i tried

class practice:
    id = None

    def __init__(self,id):
        self.id = id

a = practice('a')
b = practice('b')
c = practice('c')
d = practice('d')
e = practice('e')
f = practice('f')

x = [[a,b],[c,d],[a,b],[e,f],[a,b]]

unique_list = list()
for item in x:
    if sorted(item) not in unique_list:
        unique_list.append(sorted(item))

print(unique_list)
1
  • 2
    Pass in a comparator key to sorted should work. Commented Apr 23, 2015 at 0:45

2 Answers 2

6

If you want to compare the objects by the id:

class practice:
    id = None

    def __init__(self,id):
        self.id = id

    def __lt__(self, other):
        return other.id > self.id

    def __gt__(self, other):
        return self.id > other.id

unique_list = list()
for item in x:
    if sorted(item) not in unique_list:
        unique_list.append(sorted(item))

print(unique_list)
[[<__main__.practice object at 0x7fe87e717c88>, <__main__.practice object at 0x7fe87e717cc0>],
 [<__main__.practice object at 0x7fe86f5f79e8>, <__main__.practice object at 0x7fe86f589278>],
 [<__main__.practice object at 0x7fe86f589be0>, <__main__.practice object at 0x7fe86f589c18>]]

Depending on the functionality you want to implement all the rich comparison ordering methods you can use functools.total_ordering, you just need to define one of the methods and it will take care of the rest

from functools import total_ordering
@total_ordering
class practice:
    id = None

    def __init__(self,id):
        self.id = id

    def __lt__(self, other):
        return other.id > self.id

    def __eq__(self, other):
        return self.id == other.id

Given a class defining one or more rich comparison ordering methods, this class decorator supplies the rest. This simplifies the effort involved in specifying all of the possible rich comparison operations:

The class must define one of __lt__(), __le__(), __gt__(), or __ge__(). In addition, the class should supply an __eq__() method.

Sign up to request clarification or add additional context in comments.

1 Comment

No prob, I just added the second example as it may help if you want to add more functionality later
3

To support sorting without explicit keys for objects in Python 3, you must implement the __lt__ special method:

class practice:
    id = None

    def __init__(self,id):
        self.id = id

    def __lt__(self, other):
        return self.id < other.id

If you want the other operators to work, you'll have to implement their special methods as well, but for sorting __lt__ is all you need.

As noted in the comments, the other way to do it is to provide an explicit key function to the sorted built-in:

sorted(item, key=lambda x: x.id)

2 Comments

was trying to use the lambda method, i created a new variable and equated it to sorted(item, key=lambda x: x.id) but when i try to print out the value, i get practice object is not iterable. isn't it supposed to be a list?
@danidee The first argument to sorted has to be an iterable of practice objects. So try sorted([practice('b'), practice('a')], key=lambda x: x.id) for example. It will return a new list in the form: [practice('a'), practice('b')]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.