使用有序字典替换字典推导和默认字典
下面的代码将一个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 个回答
3
用 collections.OrderedDict
来替代 dict
的推导式和 defaultdict
的操作其实很简单。需要注意的是,OrderedDict
的速度比普通的 dict
(和 defaultdict
)稍微慢一点,但这个差距是固定的,也就是说它们在处理大数据量时的表现是一样的。
与其使用 defaultdict
,不如创建一个 OrderedDict
,然后在需要的时候用 setdefault
来设置默认值:
dd = OrderedDict()
for dc in map(etree_to_dict, children):
for k, v in dc.iteritems():
dd.setdefault(k, []).append(v)
把 dict
的推导式替换成调用 OrderedDict
,并使用一个列表或生成器表达式来生成 (key, value)
的元组,比如:
d = OrderedDict([(t.tag, OrderedDict((k, v[0] if len(v) == 1 else v)
for k, v in dd.iteritems()))])