2009-03-24 25 views
10

Me gustaría almacenar un conjunto de objetos en un montón mínimo mediante la definición de una función de comparación personalizada. Veo que hay un módulo heapq disponible como parte de la distribución de Python. ¿Hay alguna manera de usar un comparador personalizado con este módulo? Si no, ¿alguien más ha creado un montón de minutos personalizado?montón mínimo en python

+0

Para un fragmento más cómodo - (y Python 3 listo), comprobar mi respuesta a http://stackoverflow.com/questions/8875706/python-heapq-with-custom-compare-predicate/8875823#8875823 – jsbueno

Respuesta

13

Sí, hay una manera. Defina una clase de ajuste que implemente su comparador personalizado y use una lista de ellos en lugar de una lista de sus objetos reales. Eso es lo mejor que hay al usar el módulo heapq, ya que no proporciona ningún argumento key = o cmp = como lo hacen las funciones/métodos de clasificación.

def gen_wrapper(cmp): 
    class Wrapper(object): 
     def __init__(self, value): self.value = value 
     def __cmp__(self, obj): return cmp(self.value, obj.value) 
    return Wrapper 
+2

Tenga en cuenta que esto no funcionará en Python 3.0, que se deshace de __cmp__. –

+0

No, no funcionará en Python 3.0, pero eso no importa, porque Python 3.0 carece del concepto completo de "función de comparación". La pregunta simplemente no se aplica en ese caso. –

+4

Um. Debe definir __le__ en lugar de __cmp__. Eso mantendría la compatibilidad con Python 2/3. Después de todo, las operaciones y las operaciones de clasificación de heapq usan <= como su función de comparación. – tzot

15

dos opciones (aparte de la sugerencia de Devin Jeanpierre):

  1. Decora tus datos antes de utilizar el montón. Esto es el equivalente de la opción key= para clasificar. p.ej. si (por alguna razón) quería heapify una lista de números de acuerdo a su seno:

    data = [ # list of numbers ] 
    heap = [(math.sin(x), x) for x in data] 
    heapq.heapify(heap) 
    # get the min element 
    item = heappop(heap)[1] 
    
  2. El módulo heapq está implementado en Python puro. Podrías copiarlo a tu directorio de trabajo y cambiar los bits relevantes. Desde un vistazo rápido, tendría que modificar siftdown() y siftup(), y posiblemente nlargest y nsmallest si los necesita.

+0

+1: Decora tus datos. –

+1

Además, el módulo heapq se implementa tanto en C como en Python. La importación de heapq usa el módulo C si está disponible. – tzot

+0

Ah, tienes razón. Bueno, lo importante para mi segunda sugerencia es que el código python está disponible en tu directorio lib si quieres hacer tu propio código. –

Cuestiones relacionadas