[Python-es] cola con prioridad

Oswaldo Hernández listas en soft-com.es
Mie Mar 2 16:40:24 CET 2011


El 01/03/2011 19:47, Pepe Aracil escribió:
> Hola lista.
> Necesito montar una cola con prioridad, para esto esta el módulo heapq.
> Pero el caso es que necesito de vez en cuando cancelar entradas de la cola.
>
> Se me ha ocurrido meter en un "set" las entradas canceladas y comparar la
> salida del heapq con dicho "set" y desecharla si está cancelada.
>
> ¿Alguna idea mejor?
>

No se si mejor, pero a veces vamos matando moscas a cañonazos. No se si 
será este el caso.

Esta es una clase que hice para encolar funciones con sus argumentos 
pero es valida para cualquier otra cosa. Utiliza prioridades, es 
sencilla y fácilmente adaptable:

PRMAXIMA = 0
PRALTA = 25
PRMEDIA = 50
PRBAJA = 75
PRMINIMA = 100
DEFAULTPR = PRMEDIA

class JobQueue(object):
     def __init__(self):
         self._Queues = {}

     def Add(self, job, priority = DEFAULTPR, *args, **kargs):
         if not priority in self._Queues:
             self._Queues[priority] = []
         self._Queues[priority].append((job, args, kargs))

     def NextJob(self):
         if self._Queues:
             job = self._Queues[min(self._Queues)].pop(0)
             if not self._Queues[min(self._Queues)]:
                 self._Queues.pop(min(self._Queues))
             return job
         return None

     def Remove(self, job, priority = DEFAULTPR, *args, **kargs):
         self._Queues[priority].remove((job, args, kargs))
         if not self._Queues[priority]:
             self._Queues.pop(priority)

     def RemoveAll(self):
         self._Queues = {}

     def RemovePriority(self, priority):
         if priority in self._Queues:
             self._Queues.pop(priority)

     def __len__(self):
         return sum([len(self._Queues[q]) for q in self._Queues])


 >>> def TestFunc(*args, **dargs):
...     print "TestFunc:", args, dargs
...
 >>> Q = JobQueue()
 >>> Q.Add(TestFunc, PRBAJA, 1,2,3)
 >>> Q.Add(TestFunc, PRMEDIA, arg1="uno", arg2="dos")
 >>> Q.Add(TestFunc, PRALTA)
 >>>
 >>> while 1:
...     job = Q.NextJob()
...     if job:
...         job[0](*job[1], **job[2])
...     else:
...         break
...
TestFunc: () {}
TestFunc: () {'arg1': 'uno', 'arg2': 'dos'}
TestFunc: (1, 2, 3) {}



Saludos,

-- 
Oswaldo Hernández


Más información sobre la lista de distribución Python-es