Search code examples
pythonpriority-queue

Iterate through queue containing objects in python


I'm new to python and just discovered a strange error when trying to iterate through a queue.

Here's a code snippet:

frontier = q.PriorityQueue()

    for goal in goals:
        portals = findPortals(maze)
        comb_value = heuristic(startX, startY, goal[0], goal[1])
        frontier.put_nowait((comb_value, heuristic(startX, startY, goal[0], goal[1]), 0, startX, startY, startX, startY))

        for portal in portals:
            heur = portalHeuristic(maze, startX, startY, goal[0], goal[1])
            frontier.put_nowait((heur, heur, 0, startX, startY, startX, startY))

    for elem in list(frontier):
        print(elem)

When trying to print out the elements it says TypeError: 'PriorityQueue' object is not iterable. Can I fix this somehow? I tried to find some solutions on here, but I didn't really find anything I understood...


Solution

  • PriorityQueue doesn't support the internal functions that make for-loop syntax work for the data structure (such as __iter__ and next).

    Instead, you can use a while loop that checks if the Queue is empty with the empty function, and if not empty, calls get or get_nowait as needed to remove and return items from the queue as they are ready.

    Because it requires special knowledge on the part of the caller to know the meaning of consuming the next item from the queue, it would be inconvenient to support for-loop iteration. What would a for-loop do for a queue? Always assume it should consume with get_nowait immediately after successfully consuming the current item? Then it might throw an exception if the queue doesn't have any items immediately ready for return. Should it always use get and block forever waiting for each item? Then the for-loop syntax would be disguising possible complications, waiting forever.

    Rather than choosing one of these options as a default looping behavior, which may result in unexpected behavior for lots of queue use cases, the standard library implementation puts the burden on the caller to do something, like the while-loop I mentioned, to explicitly describe how to "get" each item of the queue.

    (Note: I am assuming that this PriorityQueue library / implementation is the same as from the standard library queue module).