将树保存为字典中的键,Python 3.4

时间:2014-11-04 11:44:10

标签: python xml dictionary tree

我有数百个xml文件。我有比较2 xml树的功能,如果相同则返回true。 每个xml树都有唯一的ID号,在比较中会被忽略。

现在我可以遍历所有xml文件并进行比较。但我想将树保存在像字典这样的数据结构中。但是python不允许我将树保存为键,将其id保存为值。 有没有办法让树的字典作为关键?如果没有,那么可以使用什么类型的数据结构?

例如: enter image description here

注意Tree1 = Tree2但是!= Tree3(忽略id)所以我希望我的dic或任何数据结构如下:

dic = {Tree1:[I1.i1.p1.m1, I1.i1.p1.m2], Tree3: [I1.i1.p1.m3]}

由于

2 个答案:

答案 0 :(得分:0)

字典是HashMaps。这意味着键必须是可清除的,这通常意味着要散列的对象是不可变的(列表不是有效键,而是元组的原因)。

您需要的是为您的对象生成此哈希的函数。在树状数据结构上生成哈希是一个非常重要的问题。但是,既然您已经可以制定平等,那么您必须了解一些使您的数据可识别的功能。

您始终可以在要素向量上构建哈希值。可以使用的功能:

  1. 树的深度
  2. 孩子数
  3. 对已经可用的序列化进行哈希处理

答案 1 :(得分:0)

这是一个通用的解决方案,可以说明除了某些属性之外,2 xml树是否相同。

import xml.etree.ElementTree as ET

xml1 = '<?xml version="1.0" encoding="utf-8" ?><Math mode="inline" tau="tex" xml:id="foo"><XMath>2x+3c</XMath></Math>'
xml2 = '<Math mode="inline" tau="tex" xml:id="bar"><XMath>2x+3c</XMath></Math>'

#see for more informations https://docs.python.org/3.4/library/xml.etree.elementtree.html

def almost_equals(tree1, tree2, attributes_to_ignore):
    """ Return true or false depending on the fact that tree1 and tree2 are identical except for the attributes whose the tag is in attributes to ignore. """
    #remove attributes to ignore
    for attribute in attributes_to_ignore:
        try:
            tree1.attrib.__delitem__(attribute)
        except:
            pass    
        try:
            tree2.attrib.__delitem__(attribute)
        except:
            pass

    #compare nodes
    if tree1.tag != tree2.tag:
        print(tree1.tag,"!=",tree2.tag)
        return False

    if tree1.attrib != tree2.attrib:
        print(tree1.attrib,"!=",tree2.attrib)
        return False

    if tree1.text != tree2.text:
        print(tree1.text,"!=",tree2.text)
        return False

    subtrees1 = list(tree1)
    subtrees2 = list(tree2)

    if len(subtrees1) != len(subtrees2):
        return False

    result = True
    for i in range(len(subtrees1)):
        result = result and almost_equals(subtrees1[i], subtrees2[i], attributes_to_ignore)

    return result

if __name__ == "__main__":
    xmlTree1 = ET.fromstring(xml1)
    xmlTree2 = ET.fromstring(xml2)
    print("The 2 xml trees are identical ({0})".format(almost_equals(xmlTree1, xmlTree2, ["{http://www.w3.org/XML/1998/namespace}id"])))

希望它有所帮助。 亚瑟。

编辑:您可以将XML保存为xml并按需解析它们,或者使用内置python库生成的Element对象。