【问题标题】:save a tree as a key in a dictionary, Python 3.4将树保存为字典中的键,Python 3.4
【发布时间】:2014-11-04 11:44:10
【问题描述】:

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

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

示例:

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

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

谢谢

【问题讨论】:

  • 您能否提供一个text 示例和一些实际代码?通常,对象必须实现__hash____eq__ 才能充当字典键。
  • 并非所有内容都可以是字典键,请阅读tutorialspoint.com/python/python_dictionary.htm在页面中搜索“限制”。

标签: python xml dictionary tree


【解决方案1】:

字典是 HashMap。这意味着键必须是可散列的,这通常意味着要散列的对象是不可变的(为什么列表不是有效的键,但元组是)。

您需要一个为您的对象生成此哈希的函数。在树状数据结构上生成散列是一个非常重要的问题。但是,由于您已经可以制定相等性,因此您必须对一些使您的数据可识别的特征有所了解。

您始终可以在特征向量上构建散列。可以使用的功能:

  1. 树的深度
  2. 孩子的数量
  3. 对已经可用的序列化进行散列

【讨论】:

    【解决方案2】:

    这是一个通用的解决方案,可以判断 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 对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-08
      • 1970-01-01
      • 2018-11-08
      • 1970-01-01
      • 2022-12-15
      • 2020-02-19
      相关资源
      最近更新 更多