Я нашел виновника ошибки :).
Класс queue.PriorityQueue
работает путем хранения списка элементов. Всякий раз, когда вы .put
что-то вводите, он сравнивает его, используя <
и >
, чтобы найти место для вставки. «.get» просто вытолкнет его из уже отсортированного списка.
Из-за того, что tuple
и list
нельзя сравнивать, .put
завершается ошибкой. Это также может быть связано с тем, что вы можете изменить список после, что приведет к разрыву очереди приоритетов.
Простое исправление - изменить строку в repsInS
с freqs.append([t, reps])
на freqs.append((t, reps))
.
РЕДАКТИРОВАТЬ: Похоже, что есть еще ... Очередь приоритетов упорядочивает их, используя богатые магические методы сравнения объекта. Вместо этого я заставил их использовать обычный список и сделать так, чтобы узел сохранял свой собственный вес. Это экономит сложность в классе и делает код более понятным.
Вот исправленный и полированный код.
import queue
test_str = 'testString'
test_list = [chr(i) for i in range(ord('a'), ord('z') + 1)]
class HuffmanNode:
def __init__(self, weight, left=None, right=None, info=None):
self.weight = weight
self.left = left
self.right = right
self.info = info
def hijoTemp(self):
return self.left, self.right
def get_repeats(S, T):
freqs = []
for t in T:
reps = 0
for s in S:
if s == t:
reps += 1
freqs.append((reps, t))
freqs.sort(key=lambda x: x[0], reverse=True)
return freqs # Return list of lists
def create_huffman_tree(freqs):
objs = [HuffmanNode(w, info=l) for w, l in freqs]
objs.sort(key=lambda node: node.weight, reverse=True)
while len(objs) > 1:
left, right = objs.pop(), objs.pop()
weight = left.weight + right.weight
objs.put(HuffmanNode(weight, left, right))
return objs.pop()
if __name__ == '__main__':
frecuencias = get_repeats(test_str, test_list)
huffman_tree = create_huffman_tree(frecuencias)