Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to create a python object that will be not sortable?

Tags:

python

Is there a possibility to create any python object that will be not sortable? So that will be an exception when trying to sort a list of that objects? I created a very simple class, didn't define any comparison methods, but still instances of this class are comparable and thus sortable. Maybe, my class inherits comparison methods from somewhere. But I don't want this behaviour.

like image 736
Graf Avatar asked Mar 02 '10 21:03

Graf


People also ask

How do you sort a list without a sort function in Python?

STEP 1: Declare and initialize an array. STEP 2: Loop through the array and select an element. STEP 3: The inner loop will be used to compare the selected element from the outer loop with the rest of the elements of the array. STEP 4: If any element is less than the selected element then swap the values.

Can you Unsort a list in Python?

You cannot unsort the list but you could keep the original unsorted index to restore positions. E.g. As you can see this works with duplicate values.

Can objects be sorted in Python?

The sorted() function returns a sorted list of the iterable object given. You can choose between ascending and descending order. Numbers are sorted numerically, while strings are arranged alphabetically.

How do you make a class object hashable?

An object hash is an integer number representing the value of the object and can be obtained using the hash() function if the object is hashable. To make a class hashable, it has to implement both the __hash__(self) method and the aforementioned __eq__(self, other) method.


4 Answers

You could define a __cmp__ method on the class and always raise an exception when it is called. That might do the trick.

Out of curiosity, why?

like image 88
Will McCutchen Avatar answered Sep 27 '22 16:09

Will McCutchen


As Will McCutchen has mentioned, you can define a __cmp__ method that raises an exception to prevent garden variety sorting. Something like this:

class Foo(object):
    def __cmp__(self, other):
        raise Exception()

a = [Foo(), Foo(), Foo()]
a.sort()
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 3, in __cmp__
Exception

However, you cannot truly prevent a developer from sorting a list of your objects. Using the key or cmp argument with list.sort() or with the built-in standalone sorted() function , anyone can circumvent the __cmp__ method by using a custom comparison function or sorting key.

# continuing from above
>>> a = [Foo(), Foo(), Foo()]
>>> a
[<__main__.Foo object at 0x1004a3350>, <__main__.Foo object at 0x1004a3390>,
 <__main__.Foo object at 0x1004a33d0>]

>>> a.sort(key=id, reverse=True)
>>> # or a.sort(cmp=lambda a, b: cmp(id(b), id(a)))
>>> # or sorted(a, key=id)
>>> # etc...
[<__main__.Foo object at 0x1004a33d0>, <__main__.Foo object at 0x1004a3390>,
 <__main__.Foo object at 0x1004a3350>]

As others will point out, I'm not sure there's much value in trying to prevent someone from sorting an object. If this isn't just a curious itch you're trying to scratch, what's the use case for this?

like image 41
Jarret Hardie Avatar answered Sep 27 '22 16:09

Jarret Hardie


The default list sorting uses the built-in cmp() function on its elements. The cmp() function checks if its arguments (2 elements from your list) have a __cmp__() method. If yes, this method is used for comparison. Otherwise, as in your case, the argument object IDs (return value of the built-in function id()) are used for comparison.

To let the sorting fail, you could define a comparison method which throws an Exception:

>>> class X(object):
...    def __cmp__(self, other):
...        raise StandardError # or whatever Exception you need
...
>>> l = [X(), X(), X()]
>>> l.sort()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in __cmp__
StandardError
like image 33
Oben Sonne Avatar answered Sep 27 '22 15:09

Oben Sonne


For what it's worth, in Python 3 the default will be for new items to not be comparable (and hence not sortable). In Python 2, you have to explicitly create a __cmp__ or __lt__ method, as others have said.

like image 36
Daniel Stutzbach Avatar answered Sep 27 '22 15:09

Daniel Stutzbach