Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用有序词典取代词典理解和defaultdict_Python_Xml_Dictionary_Elementtree_Xml.etree - Fatal编程技术网

Python 用有序词典取代词典理解和defaultdict

Python 用有序词典取代词典理解和defaultdict,python,xml,dictionary,elementtree,xml.etree,Python,Xml,Dictionary,Elementtree,Xml.etree,以下代码获取XML并将其转换为字典: import xml.etree.cElementTree as et tree = et.parse(path_to_xml) root = tree.getroot() xml_dict = etree_to_dict(root) 其中: def etree_to_dict(t): d = {t.tag: {} if t.attrib else None} children = list(t) if children

以下代码获取XML并将其转换为字典:

import xml.etree.cElementTree as et
tree = et.parse(path_to_xml)
root = tree.getroot()      
xml_dict = etree_to_dict(root)
其中:

def etree_to_dict(t):
    d = {t.tag: {} if t.attrib else None}
    children = list(t)
    if children:
        dd = defaultdict(list)

        for dc in map(etree_to_dict, children):
            for k, v in dc.iteritems():
                dd[k].append(v)
        d = {t.tag: {k:v[0] if len(v) == 1 else v for k, v in dd.iteritems()}}

    if t.attrib:
        d[t.tag].update(('@' + k, v) for k, v in t.attrib.iteritems())
    if t.text:
        text = t.text.strip()
        if children or t.attrib:
            if text:
              d[t.tag]['#text'] = text
        else:
            d[t.tag] = text
    return d
但是,上面的函数返回一个无序的字典。我希望它返回一个有序的字典。我不清楚如何替换一些字典理解
defaultdict
调用

输入的一个例子可以是:


关于如何替换

的任何想法将
dict
理解和
defaultdict
操作替换为
集合.OrderedDict
实例上的等效操作相当简单。请注意,
OrderedDict
s比常规dict(和
defaultdict
s)稍微慢一点,但只有一个常数(它们仍然具有相同的big-O性能)

创建一个
orderedict
而不是
defaultdict
,必要时使用
setdefault
创建默认值:

dd = OrderedDict()

for dc in map(etree_to_dict, children):
    for k, v in dc.iteritems():
        dd.setdefault(k, []).append(v)
将dict理解替换为调用
OrderedDict
,并使用生成
(键、值)
元组的列表或生成器表达式,例如:

d = OrderedDict([(t.tag, OrderedDict((k, v[0] if len(v) == 1 else v)
                                     for k, v in dd.iteritems()))])

根据定义,字典在python中是未排序的。您可以通过元组的排序列表来模拟“排序”字典,但这样会丢失快速索引。Python没有与有序映射本机等价的东西,它的dict是作为哈希表实现的。感谢@Aruistante,如果必要的话,我很乐意牺牲速度。好的,您可以将dict封装在一个类中,该类具有一个
sorted\u items
属性,该属性返回以下内容:
sorted(self.\u dict.items(),key=lambda item:item[0])
@aruistante:如果插入顺序是可以接受的(而不是按键或其他什么排序),那么
集合。OrderedDict
可能正是提问者需要的。
排序!=插入顺序
,因此我认为OP必须澄清
顺序。没有排序的图片
,它们只是保持插入顺序。如果你给他们一个排序后的输入列表,我想它可以做到这一点,但是如果你不使用它,你就不能添加元素。@Aruistante:是的,我想我是在假设提问者真正需要的是它。XML层次结构是有序的,使用
OrderedDict
s将保留该顺序(但不应用另一个顺序,如按键字母顺序)。啊,看起来OP删除了他们文章中排序的单词,所以你可能是对的@阿鲁伊斯丹特很抱歉给你带来了困惑。阅读你的评论让我意识到我真正想要的是什么。你一直都是对的。谢谢