Search code examples
pythonclasstypeerrorpriority-queuehuffman-code

Appending a self constructed class in priority que gives TypeError: '<' not supported between instances of 'str' and 'Node'


import sys
from queue import PriorityQueue

class Node(object):
    def __init__(self, data = None):
        self.value = data
        self.right = None
        self.left = None

class Huffman():
    def __init__(self, data):
        self.data = data
    
    def encoding(self):
        my_dict = {}
        for i in self.data:
            my_dict[i] = my_dict.get(i, 0)+1
        q = PriorityQueue()
        for i, j in my_dict.items():
            q.put((j,i))
        while q.qsize() >= 2:
            val_1 = q.get()
            val_2 = q.get()
            new_node_1 = Node(val_1[0]+val_2[0])
            if isinstance(val_1[1], str):
                new_node_1.left = val_1[1]
            else:
                new_node_1.left = val_1[1]
            if isinstance(val_2[1], str):
                new_node_1.right = val_2[1]
            else:
                new_node_1.right = val_2[1]
            q.put((new_node_1.value, new_node_1))

Herein, I am getting an error in while loop, after a few operations it fails to use the method q.get(), or q.put(). For example, Huffman('AADCIDCVUSHDUSHUSAHDIADHIAD').encoding() I do not want to change entire code, but just want to change priorities such that it priorities entries on the basis of first element (which is integer) only.


Solution

  • You are right, the Priority Queue doesn't know how to compare a str with a Node. You have to override the comparator functions in your Node class to let the Priority Queue know how to compare two different types.

    Example (change the comparators as you want):

    class Node(object):
        def __init__(self, data=None):
            self.value = data
            self.right = None
            self.left = None
    
        def __lt__(self, obj):
            """self < obj."""
            return self.value < obj
    
        def __le__(self, obj):
            """self <= obj."""
            return self.value <= obj
    
        def __eq__(self, obj):
            """self == obj."""
            return self.value == obj
    
        def __ne__(self, obj):
            """self != obj."""
            return self.value != obj
    
        def __gt__(self, obj):
            """self > obj."""
            return self.value > obj
    
        def __ge__(self, obj):
            """self >= obj."""
            return self.value >= obj