在XML,Python中使用if条件嵌套for循环

时间:2019-02-24 11:33:49

标签: python xml if-statement elementtree

我想在用户输入AA_codeCHAIN_ID时返回RES_POSITIONCHAIN_IDCHAIN标签的子元素,RES_POSITIONAA_CODERESIDUE标签的子元素。 RESIDUE标签也是CHAIN的子元素 标签。

我的代码仅对AA_CODE返回CHAIN_ID = "A",直到 RES_POSITION = "370"。 但是,它不会为其他CHAIN_IDs返回,而是 它应该返回。我不明白为什么会有任何帮助 不胜感激。

PS:我正在使用Elementtree。

XML示例:

<RESIDUE>
         <RES_POSITION>370</RES_POSITION>
         <AA_CODE>G</AA_CODE>
      </RESIDUE>
   </CHAIN>
   <CHAIN>
      <CHAIN_ID>B</CHAIN_ID>
      <RESIDUE>
         <RES_POSITION>371</RES_POSITION>
         <AA_CODE>S</AA_CODE>
      </RESIDUE>
  

我的返回真实结果的代码:

   chain = [seq for seq in SEQ.findall('CHAIN') if seq.findtext('CHAIN_ID') == "A"]
    print(chain)
    sequence = [res for res in SEQ.find('CHAIN') if res.findtext('RES_POSITION') == "370"]
    print(sequence)
    for seq in chain:
            for res in sequence:
                if res in seq:
                    print(res.findtext('AA_CODE'))

返回:

[<Element 'CHAIN' at 0x0000019203C83138>]
        [<Element 'RESIDUE' at 0x00000192040E4C78>]
        G
  

我的CHAIN_ID的代码为B:

chain = [seq for seq in SEQ.findall('CHAIN') if seq.findtext('CHAIN_ID') == "B"]
print(chain)
sequence = [res for res in SEQ.find('CHAIN') if res.findtext('RES_POSITION') == "371"]
print(sequence)
for seq in chain:
        for res in sequence:
            if res in seq:
                print(res.findtext('AA_CODE'))

返回:

[<Element 'CHAIN' at 0x000002EFB2254DB8>]
[]

1 个答案:

答案 0 :(得分:0)

sequence = [res for res in SEQ.find('CHAIN') if res.findtext('RES_POSITION') == "371"]

在这里,您写的是SEQ.find(...)而不是SEQ.findall(...)

这是您想要的吗? find()仅在您的XML文件中找到CHAIN的第一个匹配项,而我的猜测是,该行的第二部分(res_position == 371)对找到的元素求值为False,因此序列最终将为空列表。

此外,尽管findall返回CHAIN元素,但findall仅返回CHAIN子元素,这需要修改generator语句的if-部分。

以下是我已经实际测试过的代码;-):

chain = [seq for seq in SEQ.findall('CHAIN') if seq.findtext('CHAIN_ID') == "B"]
print(chain)
sequence = [res for res in SEQ.findall('CHAIN') if res.findtext('RESIDUE/RES_POSITION') == "371"]
print(sequence)
for seq in chain:
    for res in sequence:
        if res == seq:
            print("=> %s" % res.findtext('RESIDUE/AA_CODE'))
  • 由于序列行现在包含CHAIN元素,因此必须在RESIDUE元素名称前添加RES_POSITION和AA_CODE元素。
  • 出于相同的原因,您检查res和seq的相等性,而不是“包含性”(这是一个单词吗?)。

另一个建议-试试这个:

chain = [
    seq for seq in SEQ.findall('CHAIN')
    if seq.findtext('CHAIN_ID') == "B"
        and seq.findtext('RESIDUE/RES_POSITION') == "371"
] 
for seq in chain:
    print("=> %s" % seq.findtext('RESIDUE/AA_CODE'))

这效率更高,因为它只遍历整个数据一次,不需要嵌套的for循环。