[Python] Sorting di cose senza sort()

Daniele Varrazzo piro a develer.com
Ven 17 Lug 2009 11:19:49 CEST


On Wed, 15 Jul 2009 22:25:47 +0200, Pietro Battiston <toobaz a email.it>
wrote:
> Salve a tutti,
> 
> mi confermate che il __cmp__ default della classe object fa
> semplicemente (il confronto tra le classi, e poi) il confronto tra gli
> id?
> 
> Perché mi sembra così dalle prove che ho fatto, ma non l'ho trovato
> documentato da nessuna parte.

Grossomodo è così. La documentazione è qui: 
http://docs.python.org/reference/datamodel.html#object.__cmp__


> In realtà a me non me ne frega poi niente del particolare ordinamento:
> quello di cui ho bisogno è solo che date due istanze arbitrarie "a" e
> "b" di una stessa classe, nel corso del programma min(a,b) e min(b,a)
> restituiscano sempre la stessa.

Mi sembra che tu sia abbastanza sicuro di questo. Puoi comunque rinforzare
e rendere esplicita la cosa definendo nella tua classe un cmp in questo
modo:

class MyClass:
    def __cmp__(self, other):
        return cmp(id(self), id(other))

Nota che, esplicito o meno, questo ordinamento è stabile solo a parità di
id: non è sicuro ad esempio se fai un pickle/unpickle degli oggetti (il
che può avvenire silenziosamente ad es. serializzando gli oggetti per
passarli ad un altro processo o cacharli in memcached).

Se vuoi essere sicuro anche contro il pickling potresti usare un id univoco
da incrementare ad ogni istanza, tipo:

    import itertools

    class MyClass:
        __cmp_counter = itertools.count().next

        def __init__(self):
            self.__cmp_id = self.__cmp_counter()

        def __cmp__(self, other):
            return cmp(self.__cmp_id, other.__cmp_id)


> E ammesso che sia così: è una caratteristica del Python o di cpython?

E' una caratteristica del linguaggio, non dell'implementazione. Ma è stata
eliminata in Python 3.0

-- 
Daniele Varrazzo - Develer S.r.l. 
http://www.develer.com


Maggiori informazioni sulla lista Python