3

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...

3
  • Sounds like you don't fully understands what a priority queue does. It's usually a heap, not a linked list, which means it's unordered except the top element. Commented Nov 24, 2017 at 19:46
  • Are you using this PriorityQueue? Commented Nov 24, 2017 at 19:51
  • Also see stackoverflow.com/questions/21157739/… Commented Nov 24, 2017 at 19:56

2 Answers 2

5

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much for the explanation and the solution to my problem! :)
1

You can

for elem in frontier.queue:
        print(elem)

of course this breaks information hiding, I checked the implementation code to see that, but maybe the atribute is named self.queue and not self._queue for a reason like this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.