python3队列。优先级队列更改?

python3队列。优先级队列更改?,python,Python,我正在将我的应用程序从py27“移植”到py33。 在大多数情况下,这是相当琐碎的。也就是说,py27和py33之间有一个非常奇怪的区别 我基本上有两个线程,它们通过队列进行通信。 发送的数据类型如下: put((3,'SOME_标记',{SOME:type,of:data}) 即优先级、命令、数据 这在py27中工作得非常好,但是现在大部分到py33的转换都完成了,我不时会遇到一个奇怪的异常: return heappop(self.queue) TypeError: unorderable

我正在将我的应用程序从py27“移植”到py33。 在大多数情况下,这是相当琐碎的。也就是说,py27和py33之间有一个非常奇怪的区别

我基本上有两个线程,它们通过队列进行通信。 发送的数据类型如下:

put((3,'SOME_标记',{SOME:type,of:data})

即优先级、命令、数据

这在py27中工作得非常好,但是现在大部分到py33的转换都完成了,我不时会遇到一个奇怪的异常:

return heappop(self.queue)
TypeError: unorderable types: dict() < dict()
返回heappop(self.queue)
TypeError:无序类型:dict()

你知道这是什么,或者py27和py3之间在PriorityQueue方面发生了什么变化吗?

没有任何变化与
PriorityQueue
s有关;变化与
dict
有关,更普遍地说,与排序没有自然顺序的对象有关

问题是您试图对包含dict的两个元组进行排序,如下所示:

(3, 'SOME_TAG', {'some': 'type', 'of': 'data'})
(3, 'SOME_TAG', {'some': 'type', 'of': 'data'})
(3, 'SOME_TAG', {'some': 'othertype', 'with': 'differentdata'})
元组按字典顺序进行比较,也就是说,它们首先比较第一个元素,如果它们相等,则尝试第二个元素,如果它们相等,则尝试第三个元素,依此类推

大多数情况下,第一个或第二个元素会有所不同,因此您永远不需要比较第三个元素,因此一切都会很好

但有时,您会得到两个类似的值:

(3, 'SOME_TAG', {'some': 'type', 'of': 'data'})
(3, 'SOME_TAG', {'some': 'type', 'of': 'data'})
(3, 'SOME_TAG', {'some': 'othertype', 'with': 'differentdata'})
然后,它需要比较这两个dict来决定哪个tuple更少

这是一件毫无意义的事情。字典的项本来就是无序的,所以你怎么能决定哪一项比另一项少?事实上,即使这些项有一个固定的和可预测的元素,你在这里期望的规则是什么?第一项少是因为“
”中的“
”和“
”一起,还是因为“
”其他而更大键入“<”键入“
”或

Python2.x只是做了一些随意和无用的事情;Python3.x反而引发了一个异常

当操作数没有有意义的自然排序时,排序比较运算符(
)会引发
TypeError
异常

因此,在这些情况下,您已经遇到了问题,但是Python2.x通过偶尔默默地做一些无用的事情来隐藏问题,而3.x则让问题变得显而易见


那么,解决方案是什么?好吧,你想发生什么?我猜你实际上想对第一个元素进行排序,忽略其他元素。在这种情况下,你在Python2.x中自动得到了一些接近这一点的东西,你可能没有注意到它有时以不可预测的方式不稳定。但是如果你真的想在behavior,在这两个版本中,您必须自己编写

不幸的是,与Python中大多数排序相关的函数和对象不同,
PriorityQueue
不使用
函数。*这意味着您必须手动“修饰排序取消修饰”。但这并不太难。例如:

class TupleSortingOn0(tuple):
    def __lt__(self, rhs):
        return self[0] < rhs[0]
    def __gt__(self, rhs):
        return self[0] > rhs[0]
    def __le__(self, rhs):
        return self[0] <= rhs[0]
    def __ge__(self, rhs):
        return self[0] >= rhs[0]


*因为它使用的是隐藏的,并且
heapq
不处理键,因为“在正常列表上工作的函数”的设计排除了它…

这解释了更改发生的位置谢谢。旧方法很好,尽管你关于它被破坏的观点是正确的。本质上,我是在使用PriorityQueue来确保某些信号跳过其他命令(通常是“STOP”),只要它们在队列中,其余的顺序就不重要。我实际上刚刚试过:(3,time.time(),'SOME_标记',{'SOME':'type','of':'data'})试图提供一些可以排序的增加的内容。这也失败了(尽管我可能错过了一个。put())。我将尝试您的排序方法。这也解决了我的python2-python3优先级队列升级问题!现在我了解/理解了python2是如何以任意方式处理此问题的,我有一个后续问题。在这个修复/实现中,TupleSortingOn0是如何处理0值相同的情况的然后队列只是默认排序为某种fifo或其他标准排序?可能很明显,但我不知道-thx