I am working on a genome compression algorithm using variations of Huffman coding. I have the following piece of code in python2:
def makeHuffTree(trees):
heapq.heapify(trees)
while len(trees) > 1:
childR, childL = heapq.heappop(trees), heapq.heappop(trees)
parent = (childL[0] + childR[0], childL, childR)
heapq.heappush(trees, parent)
return trees[0]
I am trying to run it in python3. But, I am getting a Type error as follows:
TypeError: '<' not supported between instances of 'tuple' and 'str'
The input that goes into the function is a list of tuples. Say,
[(1, '35'), (1, '38'), (1, '50'), (1, 'K'), (4, 'N')]
I am confused, why it is working in python 2 but not in python3. I tried debugging the program and narrowed it down to the line I am getting the error. The module heapq has functions as follows:
def heappop(heap):
"""Pop the smallest item off the heap, maintaining the heap invariant."""
lastelt = heap.pop() # raises appropriate IndexError if heap is empty
if heap:
returnitem = heap[0]
heap[0] = lastelt
_siftup(heap, 0)
return returnitem
return lastelt
def _siftup(heap, pos):
endpos = len(heap)
startpos = pos
newitem = heap[pos]
# Bubble up the smaller child until hitting a leaf.
childpos = 2*pos + 1 # leftmost child position
while childpos < endpos:
# Set childpos to index of smaller child.
rightpos = childpos + 1
if rightpos < endpos and not heap[childpos] < heap[rightpos]:
childpos = rightpos
# Move the smaller child up.
heap[pos] = heap[childpos]
pos = childpos
childpos = 2*pos + 1
# The leaf at pos is empty now. Put newitem there, and bubble it up
# to its final resting place (by sifting its parents down).
heap[pos] = newitem
_siftdown(heap, startpos, pos)
def _siftdown(heap, startpos, pos):
newitem = heap[pos]
# Follow the path to the root, moving parents down until finding a place
# newitem fits.
while pos > startpos:
parentpos = (pos - 1) >> 1
parent = heap[parentpos]
if newitem < parent:
heap[pos] = parent
pos = parentpos
continue
break
heap[pos] = newitem
The error arises after some iterations in the siftup function on line
if rightpos < endpos and not heap[childpos] < heap[rightpos]:
I tried printing the type of rightpos and endpos, and I do not see an instance of str - every time it is tuple only.
Using python2, the function executes successfully and produces the following results after some steps.
input (trees)= [(1, '35'), (1, '38'), (1, '50'), (1, 'K'), (4, 'N')]
[(1, '35'), (1, '38'), (1, '50'), (1, 'K'), (4, 'N')]
Step 1:
[(1, '50'), (1, 'K'), (4, 'N'), (2, (1, '38'), (1, '35'))]
Step 2:
[(2, (1, '38'), (1, '35')), (4, 'N'), (2, (1, 'K'), (1, '50'))]
Step 3:
[(4, 'N'), (4, (2, (1, 'K'), (1, '50')), (2, (1, '38'), (1, '35')))]
Step 4:
(8, (4, (2, (1, 'K'), (1, '50')), (2, (1, '38'), (1, '35'))), (4, 'N'))
Step 5:
but in python 3, I am getting error after this many steps.
input (trees)= [(1, '35'), (1, '38'), (1, '50'), (1, 'K'), (4, 'N')]
[(1, '35'), (1, '38'), (1, '50'), (1, 'K'), (4, 'N')]
Step 1:
[(1, '50'), (1, 'K'), (4, 'N'), (2, (1, '38'), (1, '35'))]
Step 2:
[(2, (1, '38'), (1, '35')), (4, 'N'), (2, (1, 'K'), (1, '50'))]
Afterward, the error occurs: "TypeError: '<' not supported between instances of 'tuple' and 'str' "
I seek assistance, in making the piece of code work in python3.