'str'和'Node'的实例之间不支持'<'吗?

时间:2019-04-01 00:10:40

标签: python python-3.x

我正在尝试实现霍夫曼编码算法,但是由于优先级队列的比较而导致不断出现此错误。我的代码如下:

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',我都会遇到相同的错误

2 个答案:

答案 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__()是他们自己的反射

     

Python data model documentation

换句话说,当评估B < A时,即B.__lt__(A)B没有定义合适的__lt__()方法时,它使用A.__gt__(B)代替。

要解决此问题,请将以下内容添加到您的Node类中:

def __gt__(self,other):
    return 0 # or something else intelligent