Python 不同的结果取决于打印调用
我决定实现一个小的哈夫曼编码脚本。在一个小概率列表上测试之后,我在构建期间打印树时得到了正确的结果,如果不打印,则得到了错误的结果。问题的原因可能是什么 这是我的密码:Python 不同的结果取决于打印调用,python,python-2.7,huffman-code,Python,Python 2.7,Huffman Code,我决定实现一个小的哈夫曼编码脚本。在一个小概率列表上测试之后,我在构建期间打印树时得到了正确的结果,如果不打印,则得到了错误的结果。问题的原因可能是什么 这是我的密码: from __future__ import division import heapq class LeafNode: def __init__(self,symbol,prob): self.symbol = symbol self.prob = prob def __re
from __future__ import division
import heapq
class LeafNode:
def __init__(self,symbol,prob):
self.symbol = symbol
self.prob = prob
def __repr__(self):
return "(%s: %s)" % (self.symbol, self.prob)
class InternalNode:
def __init__(self,prob,left,right):
self.prob = prob
self.left = left
self.right= right
def __repr__(self):
return "(internal : %s)" % (self.prob)
def getDict(seq):
d = dict()
for symbol in seq:
if symbol in d:
d[symbol] += 1
else:
d[symbol] = 1
return d
def returnProbList(seq):
data = getDict(seq)
sum_of_all = sum(data.values())
l = sorted(data.items(), key=lambda x:x[1])
return [LeafNode(x[0], x[1]/sum_of_all) for x in l]
def createTree(probs):
heapq.heapify(probs)
while len(probs) > 1:
a = heapq.heappop(probs)
b = heapq.heappop(probs)
print a,b #removing this shows wrong results.
f = InternalNode(a.prob+b.prob,a,b)
heapq.heappush(probs,f)
return probs[0]
def printSymbols(tree, seq = ''):
if isinstance(tree, InternalNode):
printSymbols(tree.left, seq+'0')
printSymbols(tree.right, seq+'1')
else:
print tree.symbol, seq
s = "This is some short text I have written. It seems that space is the most common symbol."
#l = returnProbList(s)
l = []
l.append(LeafNode('a4',0.05))
l.append(LeafNode('a3',0.2))
l.append(LeafNode('a2',0.35))
l.append(LeafNode('a1',0.4))
#print l
tree = createTree(l)
printSymbols(tree)
使用pdb调试它甚至给了我不同的结果
#Without print
a4 00
a3 01
a2 10
a1 11
#With print
a1 0
a4 100
a3 101
a2 11
#With pdb
a1 0
a2 10
a3 110
a4 111
这真的与印刷无关。你的问题是:
heapq.heappush(probs,f)
f
是InternalNode
类的实例,但该类不定义任何顺序。因此,Python默认按内存地址对InternalNode
实例进行排序。这根本不是您想要的,内存地址根据您执行的其他操作(打印、运行PDB、创建或删除其他对象…)而有所不同
最简单的修复方法是向类中添加\u\cmp\u
方法:
def __cmp__(a, b):
return cmp(a.prob, b.prob)
然后输出将是一致的
编辑:嗯,您还获得了
LeafNode
实例的内存地址顺序,所以也要添加一个\uuu cmp\uu
。我从来没有说过打印是原因。我实际上想知道heapq如何知道顺序,但我希望cmp函数作为参数。感谢您的帮助。仅供参考,将(优先级,对象)
2元组与heapq
(有关改进,请参阅文档)一起使用可能更常见。但是,在您的应用程序中,直接通过.prob
属性进行比较(即使用自定义\uuu cmp\uuu
)似乎更好。那么元组是否有基于第二个元素的comp方法?序列(包括元组)使用。单击此处了解更多解释和示例。