如何不打印嵌套循环中不需要的产品?

How do I not print the unwanted products of a nested loop?

我有一个包含很多行的文件,如下所示:-

(PTQ<38>_1:0.199472,(AagrBONN<35>*_0:0.247985,(((GBG<27>_0:0.357611,(Vocar<21>_1:0.91073,Klenit<20>_2:0.326442)<26>_1:0.070751)<31>_1:0.044341,(ME<25>_0:0.3226,SM<24>_0:0.318938)<30>_1:0.054235)<33>_1:0.094663,(EFJ<29>_3:0.314696,(((AmTr<15>_8:0.147156,((Zm<5>*_22:0.077246,Os<4>*_13:0.071153)<9>_16:0.173488,(VIT<3>_16:0.086305,(AT<1>*_10:0.182135,Potri<0>*_24:0.095723)<2>_15:0.025874)<8>_15:0.051653)<14>*_13:0.038202)<19>*_10:0.092418,(TnS<13>_7:0.205925,(PILA<7>_10:0.171663,SEGI<6>*_4:0.166892)<12>_7:0.020503)<18>_7:0.040364)<23>_7:0.091012,(Cericv<17>*_12:0.154953,(Azfi<11>_7:0.103752,Sacu<10>_10:0.11457)<16>_8:0.059988)<22>_8:0.123914)<28>*_6:0.036195)<32>*_3:0.024392)<34>_2:0.01915)<37>_2:0.028257,Pp<36>_2:0.235806)<39>_2;

PTQ 和 AagrBONN 等字母是物种名称的缩写,我有第二个文件,看起来包含以下信息(各个缩写的全名):-

AT  Arabidopsis thaliana
AagrBONN    Anthoceros angustus
AmTr    Amborella trichopoda
Azfi    Azolla filiculoides
Cericv  Ceratopteris richardii
EFJ Selaginella moellendorffii
GBG Chara braunii
Klenit  Klebsormidium flaccidum
ME  Mesotaenium endlicherianum
Os  Oryza sativa
PILA    Pinus lambertiana
PTQ Marchantia polymorpha
Potri   Populus trichocarpa
Pp  Physcomitrella patens
SEGI    Sequoiadendron giganteum
SM  Spirogloea muscicola
Sacu    Salvinia cucullata
TnS Gnetum montanum
VIT Vitis vinifera
Vocar   Volvox carteri
Zm  Zea may 

对于第一个文件中的每一行,我都需要用全名替换缩写。我尝试通过以下方法解决此问题:-

我使用第二个文件制作了一个字典,其中缩写作为键,全名作为值,将这个字典保存到 pickle 文件中,并编写了一个代码来遍历第一个文件中的行和dict 并将键的所有正则表达式匹配项(这里是缩写)替换为它们各自的配对值(这里是全名)。

我目前的代码如下:-

from os import replace
import pickle
import re

def main():

    
    with open('species_dict.pkl','rb') as handle:
        the_dict = pickle.load(handle)

    with open('Base_asr.tre','rt') as the_base_file:
        the_base_file_line = the_base_file.readlines()

    for the_line in the_base_file_line:
        for the_key in the_dict:
            x = the_line.replace(the_key,the_dict[the_key])
            print(x)
        #print(x) ??    

main()

dict 只是第二个文件中 dict 格式的 tsv。

问题是我在第一个文件中有 216 行,在字典中有 20 个条目,当我打印 (x) 时,我最终得到 216 * 20 行,而对于 216 *20 行中的每一行只有一个每行替换缩写。我正在尝试找到一种只打印一次 216 行的方法。

我尝试更改 print(x) 并将其分配给第一个 for 循环,希望 x 会在每个 dict 键每行循环一次后打印出来,但这没有用,做了一些我做不到的事情真的懂了。

我知道这是因为我的嵌套循环的性质而发生的,我在概念上迷失了我如何才能得到 216 条正确的线而不是 216 * 20 条半断线。

我该怎么办?

在内部循环中,您在每次迭代中使用原始 the_line,因此您永远不会替换所有值。您替换一个值,然后从 the_line 的新版本开始并替换第二个值,依此类推

如果你想保持相同的基本代码格式,你应该在每次迭代中覆盖原来的the_line以捕获所有替换:

the_line = the_line.replace(the_key,the_dict[the_key])

现在在第一次迭代后 the_line 将是原始的第一个替换,然后下一次迭代将其分配给第二个,依此类推...

外循环你可以print(the_line)

FWIW,您可能可以使用类似以下内容的单个正则表达式处理每一行:

import re
for the_line in the_base_file_line:
    x = re.sub(r'\w+(?=<)', lambda m: the_dict[m.group()], the_line)
    print(x)