Python 从XML文件创建字典
我有一个和Python 从XML文件创建字典,python,xml,dictionary,Python,Xml,Dictionary,我有一个和XML文件,该文件如下所示: <?xml version="1.0" encoding ="utf8"?> <rebase> <Organism> <Name>Aminomonas paucivorans</Name> <Enzyme>M1.Apa12260I</Enzyme> <Motif>GGAGNNNNNGGC</Motif>
XML
文件,该文件如下所示:
<?xml version="1.0" encoding ="utf8"?>
<rebase>
<Organism>
<Name>Aminomonas paucivorans</Name>
<Enzyme>M1.Apa12260I</Enzyme>
<Motif>GGAGNNNNNGGC</Motif>
<Enzyme>M2.Apa12260I</Enzyme>
<Motif>GGAGNNNNNGGC</Motif>
</Organism>
<Organism>
<Name>Bacillus cellulosilyticus</Name>
<Enzyme>M1.BceNI</Enzyme>
<Motif>CCCNNNNNCTC</Motif>
<Enzyme>M2.BceNI</Enzyme>
<Motif>CCCNNNNNCTC</Motif>
</Organism>
然而,这本词典似乎漏掉了不少词条。我似乎能理解问题所在。任何帮助都将不胜感激
编辑
一个用户发布了一个解决方案,但随后将其删除,但我可以及时复制它:
for each_organism in rebase.findall('Organism'):
try:
enzyme = each_organism.find('Enzyme').text
except AttributeError:
continue
data_dict[enzyme] = []
for motif in each_organism.findall('Motif'):
data_dict[enzyme].append(motif.text)
return data_dict
然而,本案中返回的措辞是错误的,原因如下:
酶基序对是独一无二的。这样1种酶只有1个基序。在我的文件中,一种酶只出现一次,一个基序可以出现多次,但它属于不同的酶,所以这对酶是独一无二的。编辑下的代码所做的是:
假设并使用motif
GATC
酶解-M.APaI,另一个M.APaII
酶解-motifTCAG
。这两种酶非常相似(仅在最后一个字符I
中有所不同)。代码将两个基序结合到第一个酶上,产生{M.ApaI:['GATC','TCAG']}
我看到的第一个大问题是,你只在任何给定的生物体内搜索第一个酶。如果您想找到每种酶的发生率,应使用:
for enzyme in each_organism.findall('Enzyme'):
# add to dictionary here
第二个问题是XML的格式与您似乎正在使用字典构建的数据关系不匹配。在XML中,酶、Motif和Name都是有机体的子对象,但您将Motif指定为与酶键关联的值。你不可能知道,当你迭代的时候,哪一个应该与另一个相关联,因为它们在对象中没有任何逻辑上的分离
我可能误解了您的目的,但似乎构建有机体和酶类对象比将两个(显然)不相关的概念强制转换为键值关系更好
这可能看起来是这样的,并封装您的字段:
class Organism:
# where enzymes is an iterable of Enzyme
def __init__(self, name, enzymes):
self.name = name
self.enzymes = enzymes
你的目标是:
class Enzyme:
# where motifs is an iterable of string
def __init__(self, motifs):
self.motifs = motifs
所有这些仍然需要对XML文件进行某种更改。除非您只是逐行解析它(这显然不是XML的重点),否则我想不出任何简单的方法,您现在就能够找出哪些基序属于哪个酶
编辑:当你询问如何在每个酶节点上进行相当盲目的迭代时,假设你总是有一个单一的名称元素,每个酶有一个基序,名称后的每个元素都是酶,然后是基序(例如e-M-e-M等),你应该能够做到:
i = 0
enzymes = []
motifs = []
for element in each_organism:
# skip the first Name child
if i == 0:
continue
# if we're at an odd index, indicating an enzyme
if i % 2 == 1:
enzymes.append(element.text)
# if we're at an even index, indicating the related motif
elif i % 2 == 0:
motifs.append(element.text)
i += 1
然后,假设我提出的每一个假设,可能还有更多的假设(我甚至不是100%确定etree总是自上而下地迭代元素),都是正确的,Motions中任何给定索引的任何Motion都将属于酶中相同索引的酶。如果我还没有说清楚的话:这是难以置信的脆弱代码。你只是在寻找每个生物体的第一种酶,然后迭代所有的
基序,不管它们是否属于那种酶,看起来。你确定那是对的吗?然后(这会导致数据丢失)覆盖酶的所有基序
——但即使构建了所有基序
的列表,它们仍然会绑定到错误的酶
…是否有一种粗略的方法,可以逐行读取文件,并将每个酶和基序聚集为一个键值对(如果它们同时出现)?我知道这会破坏XML格式的全部用途,但它会work@Beginner好吧,根据我更好的判断,我已经制定了一个方法,你可能会做到这一点。不过,请记住我的警告。谢谢。我有一些类似的东西,看起来很有效。@初学者如果有帮助的话,如果你能选择答案就太好了。
i = 0
enzymes = []
motifs = []
for element in each_organism:
# skip the first Name child
if i == 0:
continue
# if we're at an odd index, indicating an enzyme
if i % 2 == 1:
enzymes.append(element.text)
# if we're at an even index, indicating the related motif
elif i % 2 == 0:
motifs.append(element.text)
i += 1