配置嵌套if循环以对数据进行分类

2024-09-24 02:16:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含以下数据的文件:

line   EF1    1     F     Flu   5.7     3.221   9.332
line   A2     1     C     Car   3.2     5.22    1.22
line   A1     1     C     Car   3.11    4.21    2.13
line   HF1    1     H     Hyd   7.11    5.11    7.11
line   EE2    1     F     Flu   5.7     3.221   9.332
line   A2     2     C     Car   3.2     5.22    1.22
line   EF1    2     F     Flu   5.7     3.221   9.332
line   EE2    2     F     Flu   5.7     3.221   9.332
line   A1     2     C     Car   3.11    4.21    2.13
line   HE2    2     H     Hyd   7.11    5.11    7.11

…1000多行。在

这里第3列表示链号。 现在我创建了不同的列表,分别命名为:EFEEH和{}。 我想做的是,如果EF1HE1都来自同一个chain number,那么在'EF list'中写{},在{}中写{}。另一方面,如果在同一个chain number中只有'EF1'而没有{},那么就把它写进'ace list'。在

期望输出为:

^{pr2}$

现在我试着

inp = filename.read().strip().split('\n')
for line in map(str.split,inp):
    codeName = line[1]
    shortName = line[3]

现在作为一个菜鸟,我真的很困惑,我如何才能构造一个if loop来完成这个检查。
请提供一些想法,我如何才能在这方面取得进展!! (我第一次被误认为是格式错误。纠正了!)在


Tags: 数据a2numberchaina1linecarlist
3条回答

我不认为你真的想要一个for循环。。。在

inp = filename.read().strip().split('\n')
inp = [line.split() for line in inp]
# sorts the input lines by the second column, so that groups appear together in order
inp = sorted(inp, key=itemgetter(1))

现在您有了一个行的列表,这些行被拆分成列

下一步,你想把它们分成第二列相同的行,对吗?在

^{pr2}$

现在,您有一个组的列表,每个组都是一个行的列表;您的数据如下所示:

groups_list = [[['EF1',   '1',     'F',     'Flu',   '5.7',     '3.221',   '9.332'],
                 ...],
               [['A2',    '2', ... ],
                 ...],
               ...
              ]

现在你可以检查一下你真正想知道的是,对于每组中的每个EF,是否有一个匹配的EH。我将为此创建一个助手函数:

def find_match(line, group, EH_list, EF_list):
    """
    returns false if no match found, returns true and appends line and match to appropriate lists otherwise
    """
    for pmatch in group:
        if line[0].startswith('EH') and pmatch[0].startswith('EF') and pmatch[0][2]==line[0][2]: # Match case 1
            EH_list.append(line)
            EF_list.append(pmatch)
            return True
        elif line[0].startswith('EF') and pmatch[0].startswith('EH') and pmatch[0][2]==line[0][2]: # Match case 2
            EF_list.append(line)
            EH_list.append(pmatch)
            return True
        else:
            return False

剩下的就简单明了了:

for group in groups_list:
    for line in group:
        if line[0][0] == 'E' and not find_match(line, group, EH, EF):
            ace.append(line)

……我想应该就是这样!我不会保证这段代码会立即运行,但它至少应该给你一个好的起点

第一次通过文件:

在我看来,最关键的部分是如何识别哪种形式的成对。我使用了以下代码片段:

splitline = line.strip().split()
identifier = "".join(splitline[1:3])[1:]
# You could also write the following, if that makes it more clear: 
identifier = splitline[1][1:] + splitline[2]

基本上,"".join(splitline[1:3])[1:]所做的就是从HF1 1生成标识符字符串F11(它省略了第一个字符),如果它只出现在“F”中,或者同时出现在“H”中(反之亦然),则基本上应该测试它。在

在本例中,EF1 with chain 1HF1 with chain 1都会产生标识符F11。第一次出现这些情况时,它设置categories['F11'] = 1。当它找到对时,它设置categories['F11'] = 2

如果我们使用一次或者两次为这个结果建立一个字典。在

建立了分类字典之后,我们可以下次再浏览该文件:

如果在categories中,一个标识符的值是1,那么我们就知道该行应该放在ace中,如果该值是2,那么我们就知道应该将该项写入F或{}。在

这个解决方案将是相当快的,因为我们正在处理字典;如果您想维护列表中的顺序,请告诉我,然后我可以相应地更新。在

代码如下:

^{pr2}$

现在您可以通过result["H"]result["F"]result["ace"]来访问这些组。在

下面是打印结果的代码:

for type in result:
    print("\n",type, "list:", "\n", "\n ".join(result[type]))
H list: 
  line   HF1    1     H     Hyd   7.11    5.11    7.11
  line   HE2    2     H     Hyd   7.11    5.11    7.11

F list: 
  line   EF1    1     F     Flu   5.7     3.221   9.332
  line   EE2    2     F     Flu   5.7     3.221   9.332

ace list: 
  line   EE2    1     F     Flu   5.7     3.221   9.332
  line   EF1    2     F     Flu   5.7     3.221   9.332

您的代码需要看起来更像这样:

with open(filename) as inp:
    for line in inp:
        tokens = line.split()
        codeName = tokens[1]
        shortName = tokens[3]

您根本无法打开文件,map()也没有真正帮助您。在

相关问题 更多 >