首页 > 解决方案 > 如何根据它们的 id 从给定的文本文件中提取字符串的第一个、第二个和最后一个实例?

问题描述

我有一个文本文件,其中包含以下形式的字符串:

66_0M100
66_1M101
66_2M102
66_3M103
66_4M103
66_5M103
67_0M100
67_1M102
67_2M105
67_3M103
67_4M106

“M”前面的数字代表实例的数量。我必须提取每个 id 的第一个、第二个和最后一个实例(id 是字符串的第一部分,在下划线之前。这里是 66 和 67)。此外,如果有任何 id 没有至少 3 个实例,则应该忽略它。

例如,id 66 和 67 的输出将是:

66_0M100 (1st instance of 66)
66_1M101 (2nd instance of 66)
66_5M103 (last instance of 66)
67_0M100 (1st instance of 67)
67_1M102 (2nd instance of 67)
67_4M106 (last instance of 67)

此输出应写入新的文本文件。

我尝试了以下代码,它给了我第一个和第二个实例,但我无法提取最后一个实例。

import numpy as np
from collections import defaultdict
data = defaultdict(list)
for fileName in ["list.txt"]:
    with open(fileName,'r') as file1:
        for line in file1:
            col1,col2 = line.split("_")
            for i in np.unique(col1):
                id1,id2 = col2.split("M")
                if ((int(id1) == 0) or (int(id1) == 1)):
                    print(line)

标签: python

解决方案


关键逻辑(将跳过无效实例并收集所有有效实例):

def ensure_instances(data_dict, id_key):
    if len(d[id_key]) < 3:
        del d[id_key]   # eliminating identifiers with less than 3 instances
    else:
        d[id_key] = d[id_key][:2] + [d[id_key][-1]]


with open('file.txt') as f:
    d = defaultdict(list)
    prev_id = None   # refers to previous identifier
    for line in f:
        id_, rest = line.split('_')
        if prev_id and id_ != prev_id:
            ensure_instances(d, prev_id)
        d[id_].append(line)
        prev_id = id_
    ensure_instances(d, id_)    # check the last identifier
    print(''.join(line for l in d.values() for line in l))

样本输出:

66_0M100
66_1M101
66_5M103
67_0M100
67_1M102
67_4M106

如果您需要将每个输入文件的输出写入单独的文本文件 - 打开目标文件(以写入模式'w')以及输入文件,例如:

with open('file.txt') as f, open('result.txt', 'w') as out_file:
    ...
    out_file.write(''.join(line for l in d.values() for line in l))

推荐阅读