python PriorityQueue 使用

tsq = queue.PriorityQueue()    
tsq.put_nowait((0, '123', ['abc', 'efg'], 0))
tsq.put_nowait((0, '456', ['abc'], 0))

上述代码能正常运行

tsq = queue.PriorityQueue()
tsq.put_nowait((0, '123', {"name":'abc', "age":'efg'}, 0))
tsq.put_nowait((0, '456', {"name":'abc'}, 0))

上述代码也能正常运行

tsq = queue.PriorityQueue()
tsq.put_nowait((0, '123', {"name":'abc', "age":'efg'}, 0))
tsq.put_nowait((0, '123', {"name":'abc'}, 0))

上述代码运行出错
heappush(self.queue, item)
TypeError: unorderable types: dict() < dict()

而改为 tsq = queue.Queue() 就能正常运行

请问这个原因是什么? heappush是什么原理?

heappush 查了下 应该是最小堆最小堆
暂时没能查到最下面的程序不过难道不是把第一个作为优先级值,后续的全部作为一个整体存入的吗?

阅读 8.4k
1 个回答

很好的问题。在隔壁的Stackoverflow上有一个answer很好的回答了你这个问题python-3-sorting-a-list-of-tuples,我来简单复述下。

首先根据文档,这个问题实际是:

>>> a = (0, '123', {"name":'abc', "age":'efg'}, 0)
>>> b = (0, '123', {"name":'abc'}, 0)
>>> c = [a, b]
>>> sorted(c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: dict() < dict()

Python 2.x 不会存在这个问题,我用本机2.7测试是可以的。但是py3就直接异常报错,这是因为py3在排序行为上发生了变化,具体见这个链接Ordering Comparisons
当对一个tuple排序时,python会从0开始对两个tuple的成员依次比较,如果两个成员相同就再比较下一个成员。问题中的tuple很有趣,前两项比较结果都相同,于是python开始比较第三个成员: a[2] vs b[2],第三个成员是dict类型,两个dict类型比较是没有意义的,但是处理方法上py2和py3有了差异,py2随机瞎排,py3则是抛出异常。

解决方案就是自己定义一个class,重写比较方法。

PS python的priorityqueue定义时可以增加和排序类似的接口key指定比较方法就好了...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题