我正在尝试实现霍夫曼编码算法,但是由于优先级队列的比较而导致不断出现此错误。我的代码如下:
class Node(object):
def __init__(self, left=None, right=None):
self.left = left
self.right = right
def children(self):
return(self.left, self.right)
def __lt__(self,other):
return 0
def create_tree(count):
print(count)
priority = queue.PriorityQueue()
for value in count:
priority.put(value)
while priority.qsize() > 1:
one, two = priority.get(), priority.get()
node = Node(one, two)
priority.put((one[0]+two[0], node))
return priority.get()
我已经尝试过在HuffmanNode类中使用__lt__的多次尝试,但总是以无法将'str'与'Node','int'或'tuple'进行比较。我想知道是否有可能做到这一点,任何建议将不胜感激。
编辑:同样,create_tree的计数是元组列表,如下所示: [(1,'a'),(1,'b'),(2,'c')]
应该产生错误的代码:[(1,113),(1,107),(1,98),(1,120),(1,106),(1,118),(1,108 ),(1、122),(1、121),(1、100),(1、87),(1、70),(1、10),(2、84),(2、117), (2,99),(2,119),(2,102),(2,109),(2,97),(2,46),(3,110),(3,112),(4 ,114),(4、115),(4、116),(4、103),(5、104),(5、101),(7、105),(8、111),(18、32 )]
还意识到我更改了代码,因此它使用ascii值而不是字符串,但是无论是'int'还是'str',我都会遇到相同的错误
答案 0 :(得分:2)
这是直接从PriorityQueue
的文档中删除的:
首先检索最低价值的条目(最低价值的条目 是
sorted(list(entries))[0])
返回的那个。典型图案 用于输入的是一个元组,格式为:(priority_number, data)
。如果数据元素不可比,则可以将数据包装在 忽略数据项并且仅比较优先级的类 数字。
他们给出的示例代码是:
from dataclasses import dataclass, field
from typing import Any
@dataclass(order=True)
class PrioritizedItem:
priority: int
item: Any=field(compare=False)
使用您为count = [(1, 'a'), (1, 'b'), (2, 'c')]
提供的示例:
def create_tree(count):
print(count)
priority = queue.PriorityQueue()
for value in count:
priority.put(value)
while priority.qsize() > 1:
one, two = priority.get(), priority.get() # one == (1, 'a'); two == (1, 'b')
node = Node(one, two) # node == Node(left=(1, 'a'), right=(1, 'b'))
priority.put((one[0]+two[0], node)) # (2, Node(left=(1, 'a'), right=(1, 'b')) <== error here
return priority.get()
当您的代码将(2, Node(left=(1, 'a'), right=(1, 'b'))
添加到队列中其他元素PriorityQueue
时,(2, 'c')
具有相同的优先级,因此数据元素用于排序。
因此,您需要明确地忽略按数据排序(有关指导,请参见上面的docs示例),或定义'c'
相对于Node(left=(1, 'a'), right=(1, 'b'))
的排序方式并实现它。例如,如果您始终希望Node
相对于其他某种数据类型排在最后:
def __lt__(self, other):
return True
def __gt__(self, other):
return False
反之亦然:
def __lt__(self, other):
return False
def __gt__(self, other):
return True
还是更复杂的东西?
答案 1 :(得分:1)
实现__lt__()
时,将创建Node < int
的比较,而不是int < Node
。
要获取此信息,我们需要反转操作:
这些方法没有交换参数版本(当左参数不支持该操作但右参数支持该操作时使用);相反,
__lt__()
和__gt__()
是彼此的反射,__le__()
和__ge__()
是彼此的反射,而__eq__()
和__ne__()
是他们自己的反射
换句话说,当评估B < A
时,即B.__lt__(A)
和B
没有定义合适的__lt__()
方法时,它使用A.__gt__(B)
代替。
要解决此问题,请将以下内容添加到您的Node
类中:
def __gt__(self,other):
return 0 # or something else intelligent