【问题标题】:Replacing dictionary comprehensions and defaultdict by ordered dictionaries用有序字典替换字典理解和 defaultdict
【发布时间】:2014-06-18 13:56:54
【问题描述】:

以下代码采用 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

但是,上面的函数返回一个无序字典。我希望它改为返回 ordered 字典。我不清楚如何替换一些 字典理解defaultdict 调用。

输入示例如下:http://www.w3schools.com/xml/plant_catalog.xml

关于如何替换的任何想法

【问题讨论】:

  • 字典,根据定义,在 python 中是未排序的。您可以通过已排序的元组列表模拟“已排序”字典,但会丢失快速索引。 Python 没有原生的有序映射等价物,它的字典被实现为哈希表。
  • 谢谢@aruisdante,如有必要,我很乐意牺牲速度。
  • 好吧,你可以在一个类中包装一个字典,该类有一个 sorted_items 属性,该属性返回以下内容:sorted(self._dict.items(), key = lambda item : item[0])
  • @aruisdante:如果插入顺序是可以接受的(而不是按键排序或其他),那么collections.OrderedDict 可能正是提问者所需要的。
  • sorted != insertion-ordered,所以我想OP必须澄清

标签: python xml dictionary elementtree xml.etree


【解决方案1】:

collections.OrderedDict 实例上的等效操作替换dict 理解和defaultdict 操作相当简单。请注意,OrderedDicts 比常规 dicts(和 defaultdicts)慢一点,但只是一个常数因素(它们仍然具有相同的 big-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)

用产生(key, value)元组的列表或生成器表达式替换对OrderedDict的调用,例如:

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

【讨论】:

  • OrderedDicts 没有排序,它们只是保持插入顺序。如果您向他们传递一个排序的输入列表,我想它会实现这一点,但是您将无法添加元素而不采取措施。
  • @aruisdante:是的,我想我假设这是提问者真正需要的。 XML 层次结构是有序的,使用OrderedDicts 将保留该顺序(但不会应用另一个顺序,例如按字母顺序)。
  • 啊,看来 OP 从他们的帖子中删除了 sorted 这个词,所以你可能是对的!
  • @aruisdante 很抱歉造成混乱。阅读您的 cmets 让我意识到我真正想要的是什么。你一直都是对的。谢谢
猜你喜欢
  • 2018-07-28
  • 2016-09-17
  • 1970-01-01
  • 1970-01-01
  • 2015-09-26
  • 1970-01-01
  • 2021-07-24
  • 1970-01-01
  • 2015-10-30
相关资源
最近更新 更多