问题描述
我正在研究使用霍夫曼编码的变体的基因组压缩算法。我在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]
我正在尝试在python3中运行它。但是,我收到如下类型错误:
TypeError: '<' not supported between instances of 'tuple' and 'str'
[(1,'35'),(1,'38'),'50'),'K'),(4,'N')]
我很困惑,为什么它可以在python 2中工作而不能在python3中工作。 我尝试调试程序并将其范围缩小到出现错误的行。 模块heapq具有以下功能:
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,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
if rightpos < endpos and not heap[childpos] < heap[rightpos]:
我尝试打印rightpos
和endpos
的类型,但没有看到str的实例-每次仅是元组。
使用python2,该函数可以成功执行,并在某些步骤后产生以下结果。
input (trees)= [(1,'N')]
[(1,'N')]
Step 1:
[(1,'N'),(2,'35'))]
Step 2:
[(2,'35')),'50'))]
Step 3:
[(4,'50')),'35')))]
Step 4:
(8,'35'))),'N'))
Step 5:
但是 在python 3中,经过这么多步骤后,我得到了错误。
input (trees)= [(1,'50'))]
此后,发生错误:“ TypeError:'tuple'和'str'的实例之间不支持'
解决方法
所以,我想我已经找到解决问题的方法。问题是由于:python 2允许在字符串和元组之间进行比较,但不允许python3。
更改267行:
if rightpos < endpos and not heap[childpos] < heap[rightpos]:
到
if rightpos < endpos and not heap[childpos][0] < heap[rightpos][0]:
和第212行:
if newitem < parent:
到
if newitem[0] < parent[0]:
在图书馆https://github.com/python/cpython/blob/3.8/Lib/heapq.py
上解决了我的问题。
我在本地重写了功能。