Python 用有序词典取代词典理解和defaultdict
以下代码获取XML并将其转换为字典: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
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删除了他们文章中排序的单词,所以你可能是对的@阿鲁伊斯丹特很抱歉给你带来了困惑。阅读你的评论让我意识到我真正想要的是什么。你一直都是对的。谢谢