Python 如何重写此函数以实现OrderedICT?
我有下面的函数,它完成了将XML文件解析为字典的粗略工作 不幸的是,由于Python字典没有排序,因此我无法按照自己的意愿循环遍历节点 如何更改此设置,使其输出一个有序字典,当与Python 如何重写此函数以实现OrderedICT?,python,xml,collections,lxml,Python,Xml,Collections,Lxml,我有下面的函数,它完成了将XML文件解析为字典的粗略工作 不幸的是,由于Python字典没有排序,因此我无法按照自己的意愿循环遍历节点 如何更改此设置,使其输出一个有序字典,当与for循环时,该字典反映节点的原始顺序 def simplexml_load_file(file): import collections from lxml import etree tree = etree.parse(file) root = tree.getroot()
for
循环时,该字典反映节点的原始顺序
def simplexml_load_file(file):
import collections
from lxml import etree
tree = etree.parse(file)
root = tree.getroot()
def xml_to_item(el):
item = None
if el.text:
item = el.text
child_dicts = collections.defaultdict(list)
for child in el.getchildren():
child_dicts[child.tag].append(xml_to_item(child))
return dict(child_dicts) or item
def xml_to_dict(el):
return {el.tag: xml_to_item(el)}
return xml_to_dict(root)
x = simplexml_load_file('routines/test.xml')
print x
for y in x['root']:
print y
产出:
{'root':{
“a”:[1'],
'aa':[{'b':[{'c':['2']},'2']}],
'aaaa':[{'bb':['4']}],
“aaa”:[3'],
“AAAA”:[5']
}}
A.
aa
aaaa
aaa
AAAA
如何实现collections.OrderedDict
,以确保获得正确的节点顺序
供参考的XML文件:
1.
2.
2.
3.
4.
5.
答案中列出了许多可能的OrderedICT实施方案:
通过复制其中一个实现,您可以创建自己的OrderedICT模块,以便在自己的代码中使用。我假设您没有访问OrderedDict的权限,因为您正在运行的Python版本
您问题的一个有趣方面是可能需要defaultdict功能。如果需要,可以实现\uuuuu missing\uuuu
方法以获得所需的效果。您可以使用新的dict
子类,该子类在2.7版中添加到标准库的集合
模块中✶。实际上,您需要的是一个不存在的有序的
+defaultdict
组合,但是可以通过子类化orderedict
来创建一个组合,如下所示:
✶如果您的Python版本没有OrderedDict
,那么您应该可以使用Raymond Hettinger的ActiveState配方作为基类。
测试XML文件生成的输出如下所示:
{'root':
有序的(
[('a',['1']),
("aa","OrderedDict"("b","OrderedDict"("c","2"),"2,
('aaa',['3']),
("aaaa","OrderedDict"(""bb","4")]],,
(‘AAAA’,[‘5’]))
]
)
}
A.
aa
aaa
aaaa
AAAA
我认为这很接近你想要的
次要更新:
添加了一个
\uuuu reduce\uuu()
方法,该方法将允许正确地对类的实例进行pickle和unpickle。对于这个问题,这不是必需的,但是在一个问题中出现了。来自martineau的配方对我有效,但是它与从DefaultDict继承的方法copy()有问题。以下方法解决了这一缺点:
class OrderedDefaultDict(OrderedDict):
#Implementation as suggested by martineau
def copy(self):
return type(self)(self.default_factory, self)
请考虑,这个实现没有深度拷贝,这似乎是默认字典,而不是在大多数情况下做的正确的事情。一些修复:A)在3.x中,您需要更改
.iterms()
对.items()
的调用(或者您可以使用six
库来实现2.x/3.x兼容性b),除非您希望具有任意或不同的顺序。@smci:我已经修改了该代码,使其在Python 2.7和3.2+中都能工作。您不需要在Python 3.6+中使用它。您可以只使用defaultdict,默认情况下它维护键的顺序
class OrderedDefaultDict(OrderedDict):
#Implementation as suggested by martineau
def copy(self):
return type(self)(self.default_factory, self)