用有序词典替换字典理解和defaultdict

时间:2014-05-02 00:01:00

标签: 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:
        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 这些调用。

输入的示例可以是:http://www.w3schools.com/xml/plant_catalog.xml

关于如何替换的任何想法

1 个答案:

答案 0 :(得分:3)

使用dict实例上的等效操作替换defaultdict理解和collections.OrderedDict操作相当简单。请注意OrderedDict s比常规dicts(和defaultdict s)慢一点,但只有一个常数因子(它们仍具有相同的大O性能)。

而不是defaultdict,创建OrderedDict并使用setdefault在必要时创建默认值:

dd = OrderedDict()

for dc in map(etree_to_dict, children):
    for k, v in dc.iteritems():
        dd.setdefault(k, []).append(v)

使用带有OrderedDict元组的列表或生成器表达式调用(key, value)来替换dict理解,例如:

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