Issue 17794: Add a key parameter to PriorityQueue (original) (raw)
Created on 2013-04-19 00:37 by Claymore, last changed 2022-04-11 14:57 by admin. This issue is now closed.
Messages (11)
Author: Carlos Ferreira (Claymore)
Date: 2013-04-19 00:37
I'm using Priority Queues and followed the Python documentation for a simple example.
From Queue documentation in Python 3.3 http://docs.python.org/3.3/library/queue.html " The lowest valued entries are retrieved first (the lowest valued entry is the one returned by sorted(list(entries))[0]). A typical pattern for entries is a tuple in the form: (priority_number, data). "
Then I tried this simple code.
pq = PriorityQueue() pq.put_nowait((0, {'a':1})) pq.put_nowait((0, {'a':2})) Traceback (most recent call last): File "", line 1, in File "/usr/lib/python3.3/queue.py", line 187, in put_nowait return self.put(item, block=False) File "/usr/lib/python3.3/queue.py", line 146, in put self._put(item) File "/usr/lib/python3.3/queue.py", line 230, in _put heappush(self.queue, item) TypeError: unorderable types: dict() < dict()
Is this a normal behaviour? I'm not sure if this should be declared as a bug...
Instead of sticking to the first argument that indicates the priority, the heapq algorithm checks the second field and tries to order the dictionaries.
I solved this annoyance by adding a third field, the object ID. Since the object ID is actually its address in memory, every object will have a different ID. Also, since the queue entries will have the same priority (zero), the id value is used to order the tuples in the heap queue.
pq = PriorityQueue() a = {'a':1} b = {'a':2} pq.put_nowait((0, id(a), a)) pq.put_nowait((0, id(b), b))
Author: R. David Murray (r.david.murray) * 
Date: 2013-04-19 00:49
It is a bug of some sort. A doc bug if nothing else. This is probably due to the fact that everything was sortable in python2, and the doc and/or code hasn't been updated to account for the fact that many things aren't in Python3.
Author: Daniel Wong (allyourcode) *
Date: 2013-04-25 05:48
from the peanut gallery:
This looks right to me; you are seeing that PriorityQueue is trying to compare dicts, because that's how tuple comparison works: it is lexicographic. Since the first element of the two tuples that you are trying to insert have the same value, comparison of the two tuple reduces to comparing the second elements.
Your work around also looks good to me.
Author: Mark Dickinson (mark.dickinson) * 
Date: 2013-04-25 19:09
Hmm. It's true that Python 3's comparison rules make PriorityQueue a bit less useful in its current form.
One possible workaround could be to introduce an optional "key" argument to the constructor that provides a callable used to map objects added to the queue to their priorities. The default key would map each object to itself, as before, but for a use-case like this one the key could just be lambda x: x[0].
Author: Mark Dickinson (mark.dickinson) * 
Date: 2013-04-25 19:57
Example patch. Items with equal priority are retrieved in LIFO order.
Author: Mark Dickinson (mark.dickinson) * 
Date: 2013-04-25 20:02
Hmm. This looks like a duplicate of #7174.
Author: Mark Dickinson (mark.dickinson) * 
Date: 2013-04-25 20:10
Fixed patch.
Author: Raymond Hettinger (rhettinger) * 
Date: 2013-04-26 05:48
I'm working on this one. Expect a patch shortly.
Author: Daniel Wong (allyourcode) *
Date: 2013-04-27 05:38
btw, I have a related patch: http://bugs.python.org/issue17834 Chances of it being accepted aren't looking good right now though.
Author: Serhiy Storchaka (serhiy.storchaka) * 
Date: 2013-04-27 08:20
Related issues: , .
See also , and .
Author: Raymond Hettinger (rhettinger) * 
Date: 2019-08-24 00:25
Starting in Python 3.7, dataclasses made it trivially easy to work around this issue. The PriorityQueue docs have a worked out example of how to do this: https://docs.python.org/3/library/queue.html#queue.PriorityQueue
History
Date
User
Action
Args
2022-04-11 14:57:44
admin
set
github: 61994
2019-08-24 00:25:31
rhettinger
set
status: open -> closed
resolution: out of date
messages: +
stage: resolved
2014-05-12 17:58:31
eric.snow
set
nosy: + eric.snow
2013-04-27 08:20:52
serhiy.storchaka
set
nosy: + serhiy.storchaka
title: Priority Queue -> Add a key parameter to PriorityQueue
messages: +
versions: - Python 3.3
type: behavior -> enhancement
2013-04-27 05:38:02
allyourcode
set
messages: +
2013-04-26 07:13:44
mark.dickinson
set
nosy: - mark.dickinson
2013-04-26 07:13:28
mark.dickinson
set
files: - issue17794.patch
2013-04-26 05:48:59
rhettinger
set
assignee: rhettinger
messages: +
2013-04-25 20:11:13
mark.dickinson
set
files: - issue17794.patch
2013-04-25 20:10:59
mark.dickinson
set
files: + issue17794.patch
messages: +
2013-04-25 20:02:01
mark.dickinson
set
messages: +
2013-04-25 19:58:44
mark.dickinson
set
files: - issue17794.patch
2013-04-25 19:58:33
mark.dickinson
set
files: + issue17794.patch
2013-04-25 19:57:27
mark.dickinson
set
files: + issue17794.patch
keywords: + patch
messages: +
2013-04-25 19:09:34
mark.dickinson
set
nosy: + mark.dickinson
messages: +
2013-04-25 05:48:55
allyourcode
set
nosy: + allyourcode
messages: +
components: + Library (Lib), - Interpreter Core
2013-04-19 00:49:23
r.david.murray
set
nosy: + rhettinger, r.david.murray
messages: +
versions: + Python 3.4
2013-04-19 00:37:22
Claymore
create