2010-10-17 15 views

Respuesta

30

heapq tipo de objetos de la misma manera list.sort no, por lo que sólo definir un método __cmp__() dentro de su definición de clase, lo que compararse con otra instancia de la misma clase:

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

Obras en Python 2.x

En uso 3.x:

def __lt__(self, other): 
    return self.intAttribute < other.intAttribute 
+4

'__cmp__' se ha ido en 3.x. Use '__lt__' en su lugar. –

+7

'__lt__' también funciona en Python 2, por lo que es mejor evitar' __cmp__' por completo. –

+8

Del mismo modo que puede ordenar cualquier clasificación según un criterio que no sea la ordenación natural del objeto (por ejemplo, 'cmp' y' key' para 'sort'), debería poder decirle a 'heapq' que ordene en función de un llave diferente En otras palabras, no debería tener que * redefinir el objeto en sí * para cambiar una estructura de datos particular que lo contiene; Debería poder decir la estructura de datos en sí misma. Esta es una pieza fundamental notable que falta en la API 'heapq'. –

3

Lamentablemente, no se puede, aunque esta es una función que a menudo se solicita.

Una opción sería insertar (clave, valor) tuplas en el montón. Sin embargo, eso no funcionará si los valores arrojan una excepción cuando se comparan (se compararán en el caso de un empate entre las claves).

Una segunda opción sería definir un método __lt__ (menor que) en la clase que usará el atributo apropiado para comparar los elementos para la clasificación. Sin embargo, eso podría no ser posible si los objetos fueron creados por otro paquete o si necesita que se comparen de manera diferente en otro lugar del programa.

Una tercera opción sería usar la clase sortedlist del módulo blist (descargo de responsabilidad: soy el autor). El constructor para sortedlist toma un parámetro key que le permite especificar una función para devolver la clave de clasificación de un elemento, similar al parámetro key de list.sort y sorted.

+0

Eliminé mi comentario anterior ya que mi problema con 'blist' era probablemente un PEBCAK (gracias de nuevo por su módulo), así que solo duplico la primera parte del comentario anterior: Siempre es posible definir una clase con' __lt__ 'a través de subclases o por encapsulación. – tzot

23

De acuerdo con el ejemplo de la documentation, puede utilizar tuplas, y se va a clasificar por el primer elemento de la tupla:

>>> h = [] 
>>> heappush(h, (5, 'write code')) 
>>> heappush(h, (7, 'release product')) 
>>> heappush(h, (1, 'write spec')) 
>>> heappush(h, (3, 'create tests')) 
>>> heappop(h) 
(1, 'write spec') 

Así Si no desea (¿o no puede hacerlo?) hacer un método __cmp__, puede extraer manualmente su clave de clasificación en el momento del envío.

Tenga en cuenta que si los primeros elementos en un par de tuplas son iguales, se compararán otros elementos. Si esto no es lo que desea, debe asegurarse de que cada primer elemento sea único.

Cuestiones relacionadas