Вставка в приоритетную очередь только с использованием первого аргумента в python

Как вставить элементы в очередь с приоритетами, но при этом убедиться, что в качестве приоритета он принимает только первый заданный аргумент. Например:

    #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))

Я хотел бы, чтобы первые два заявления были помещены в priorityQueue LIFO. Как бы я это сделал?

2 ответа

Передайте аргументы как отдельный кортеж:

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

Если вы хотите, чтобы элементы с равным приоритетом возвращались в порядке LIFO, вы должны добавить значение count к своим ключам:

# 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))

Это делает ваши значения четырьмя, а не тремя (поэтому вам нужно обновить код, который вы используете для доступа к значениям). Второе значение будет неуклонно уменьшаться (count дает последовательно увеличивающиеся целые числа навсегда, и мы их отрицаем). Если первые значения двух кортежей в очереди равны, вторые значения будут сравниваться, а последнее добавленное значение всегда будет наименьшим (и выбрано в очереди).

Кстати, если вы не используете свою очередь для синхронизации данных между несколькими потоками, вы, вероятно, должны использовать heapq функции модуля на регулярной listвместо того, чтобы использовать queue.PriorityQueue пример. Последний использует heapq реализовать внутреннюю логику, но она также выполняет блокировку, которая вам, вероятно, не нужна (для однопоточного кода это бессмысленные накладные расходы).

Другие вопросы по тегам