David
David

Reputation: 1438

Inserting into a priority queue only using the first argument in python

How do I insert items into a priority queue, but ensure that it only takes as it's priority the first argument given. For example:

    #push up
    if((pacman_r != 0 ) and (cellGrid[pacman_r-1][pacman_c].what != '%')):
        priorityQueue.put((4, pacman_r-1, pacman_c))
    #push left 
    if ((pacman_c != 0) and (cellGrid[pacman_r][pacman_c-1].what != '%')):
        priorityQueue.put((4, pacman_r, pacman_c-1))
    #push right
    if ((pacman_c != c) and (cellGrid[pacman_r][pacman_c+1].what != '%')):
        priorityQueue.put((9, pacman_r, pacman_c+1))
    #push down
    if((pacman_r != r ) and (cellGrid[pacman_r+1][pacman_c].what != '%')):
        priorityQueue.put((1, pacman_r+1, pacman_c))

I would like the top two if statements to be placed into priorityQueue LIFO. How would I do this?

Upvotes: 0

Views: 700

Answers (2)

Blckknght
Blckknght

Reputation: 104852

If you want equal priority elements to be returned in a LIFO order, you should add a count value to your keys:

# put this with your other import statements
from itertools import count

# put this near where you define your priority queue
counter = count()

#later, add the counter's latest value as a second key value:
#push up
if((pacman_r != 0 ) and (cellGrid[pacman_r-1][pacman_c].what != '%')):
    priorityQueue.put((4, -next(counter), pacman_r-1, pacman_c))
#push left 
if ((pacman_c != 0) and (cellGrid[pacman_r][pacman_c-1].what != '%')):
    priorityQueue.put((4, -next(counter), pacman_r, pacman_c-1))
#push right
if ((pacman_c != c) and (cellGrid[pacman_r][pacman_c+1].what != '%')):
    priorityQueue.put((9, -next(counter), pacman_r, pacman_c+1))
#push down
if((pacman_r != r ) and (cellGrid[pacman_r+1][pacman_c].what != '%')):
    priorityQueue.put((1, -next(counter), pacman_r+1, pacman_c))

This makes your values be four-tuples, rather than three-tuples (so you'll need to update the code you use to access the values). The second value will be steadily decreasing (count yields successively increasing integers forever, and we're negating them). If the first values of two tuples in the queue are equal, the second values will be compared and the most recently added one will always be the smallest (and so selected by the queue).

By the way, unless you're using your queue to synchronize data between multiple threads, you should probably be using the heapq module's functions on a regular list, rather than using a queue.PriorityQueue instance. The latter uses heapq to implement its logic internally, but it also does a bunch of locking that you probably don't need (for single threaded code it is pointless overhead).

Upvotes: 0

perreal
perreal

Reputation: 98118

Pass the arguments as a separate tuple:

 priorityQueue.put( (4, (pacman_r-1, pacman_c)) )

Upvotes: 1

Related Questions