So, I have a class P
. I want to two priority queues of objects of type P
, as well as a priority queue of objects of type P
. However, I want to order one of them on P.x
, and order the other on P.y
. Now, queue.PriorityQueue.put()
does not support a key function, so I resorted to doing the following:
class P:
...
def __lt__(self, other):
return self.y < other.y
...
However, this does not allow for sorting based on P.x
, and at the same time, I want to peek one of the queues but not the other, and queue.PriorityQueue
does not have a peek
function. Therefore, I replaced one of the priority queues with a sorted list instead. I can't use the SortedContainers
library, because this is for a homework assignment and I can't guarantee that the grading server has it installed, so I turned to using bisect.insort
.
The only problem, however, is that bisect.insort
also does not support key functions. Therefore, I had to write my own function binary_insert(lst, item, key)
to accomplish this task, and then I call it with binary_insert(lst, item, key = lambda i: i.x)
. This feels like a hack, since I'm writing my own binary insertion function, and binary insertion is such a core computer science concept that this must have come up before.
One way to do it would be to have the list store tuples of the form (x, p)
, and have the priority queue store tuples of the form (y, p)
. But, is there any other way to internalize these attributes into P
itself? Otherwise, I will have to unpack a tuple every time I pop off an item, and this may cause my program to become littered with unused variables.
Perhaps you can subclass PriorityQueue
to do the tuples for you, something like this (totally untested code):
class MyPriorityQueue(PriorityQueue):
def _put(self, item):
super()._put((item.x, item))
def _get(self):
return super()._get()[1]