【问题标题】:How to group lines by ID in a file with ID line followed by values lines?如何在 ID 行后跟值行的文件中按 ID 对行进行分组?
【发布时间】:2020-08-30 10:23:03
【问题描述】:

我生成的序列文件如下:

>rpl-7
ATGGCTCCAAC
>rpl-7
AAGAAAGTGCCACAGGTTCCAGAAAC
>rpl-8
AAGAACAAGGAGAAGAAGACCCAATACTTCAAGCGTGC
>rpl-8
GCTCTCCAGATCCTCCGTCTTCGTCAGATCAA
>rpl-8
AAGTTCAACATCATCTGTCTTGAGGA

我想合并相同ID的序列,就这样:

>rpl-7
ATGGCTCCAAC
AAGAAAGTGCCACAGGTTCCAGAAAC
>rpl-8
AAGAACAAGGAGAAGAAGACCCAATACTTCAAGCGTGC
GCTCTCCAGATCCTCCGTCTTCGTCAGATCAA
AAGTTCAACATCATCTGTCTTGAGGA

我用python判断'>'开头的字符串是否相同,如果相同则继续增加序列。但是这个方法不能输出第一个ID。另外我觉得awk用起来会比较方便,可惜我对awk不熟悉。你知道怎么做吗?谢谢。

【问题讨论】:

  • 抱歉,您能详细说明rpl 是什么吗?
  • rpl是指核糖体蛋白大亚基。这点不重要,可以看作是一个独特的标签。
  • 好吧,我在想 > 是一些 shell 输出并感到困惑
  • 你能说出它到底是什么吗?存储在列表等中的文件名或字符串
  • 您可以发布您已有的代码吗?您可以将 id 的 Map 作为键,将字符串列表作为值来保存结果。

标签: python linux string dictionary parsing


【解决方案1】:

在输入文件上循环,以rpl-id为键分组到字典并将值附加到列表中:


rpl_dict = {}

with open('rpl_input.txt') as rpl_input_file:
    lines = rpl_input_file.readlines()
    for line in lines:
        # Fetching current `rpl-id`
        if line.startswith('>rpl'):
            rpl_key = line.strip()
        # Fetching current `rpl-value`
        else:
            rpl_value = line.strip()
            # Appending current `rpl-value`
            if rpl_key not in rpl_dict.keys():
                rpl_dict[rpl_key] = []
            rpl_dict[rpl_key].append(rpl_value)

# {'>rpl-7': ['ATGGCTCCAAC', 'AAGAAAGTGCCACAGGTTCCAGAAAC'], '>rpl-8': ['AAGAACAAGGAGAAGAAGACCCAATACTTCAAGCGTGC', 'GCTCTCCAGATCCTCCGTCTTCGTCAGATCAA', 'AAGTTCAACATCATCTGTCTTGAGGA']}
print(rpl_dict)

with open('rpl_output.txt', 'w') as rpl_output_file:
    for rpl_id, rpl_values in rpl_dict.items():
        rpl_output_file.write(f'{rpl_key}\n')
        for v in rpl_values:
            rpl_output_file.write(f'{v}\n')

输出文件:

>rpl-8
ATGGCTCCAAC
AAGAAAGTGCCACAGGTTCCAGAAAC
>rpl-8
AAGAACAAGGAGAAGAAGACCCAATACTTCAAGCGTGC
GCTCTCCAGATCCTCCGTCTTCGTCAGATCAA
AAGTTCAACATCATCTGTCTTGAGGA

【讨论】:

  • 非常感谢,我之前的脚本没有使用字典,这个方法解决了问题。
【解决方案2】:

您可以使用正则表达式来执行此操作。由于您提到了文件,因此我添加了换行符,您可以将其替换为文件的内容。

import re

regex = r'rpl-\d\n.*(?:$|\n)'
dic = {}
test_str = (">rpl-7\n"
    "ATGGCTCCAAC\n"
    ">rpl-7\n"
    "AAGAAAGTGCCACAGGTTCCAGAAAC\n"
    ">rpl-8\n"
    "AAGAACAAGGAGAAGAAGACCCAATACTTCAAGCGTGC\n"
    ">rpl-8\n"
    "GCTCTCCAGATCCTCCGTCTTCGTCAGATCAA\n"
    ">rpl-8\n"
    "AAGTTCAACATCATCTGTCTTGAGGA\n")

matches = re.finditer(regex, test_str, re.MULTILINE)

for  match in matches:
    rpl,pro = match.group().split('\n')
    if rpl in dic:
        dic[rpl] = dic[rpl]+pro
    else:
        dic[rpl] = pro

输出:

{'rpl-7': 'ATGGCTCCAACAAGAAAGTGCCACAGGTTCCAGAAAC',
 'rpl-8': 'AAGAACAAGGAGAAGAAGACCCAATACTTCAAGCGTGCGCTCTCCAGATCCTCCGTCTTCGTCAGATCAAAAGTTCAACATCATCTGTCTTGAGGA'}

【讨论】:

    【解决方案3】:

    这是另一种解决方案,

    input_ = """>rpl-7
    ATGGCTCCAAC
    >rpl-7
    AAGAAAGTGCCACAGGTTCCAGAAAC
    >rpl-8
    AAGAACAAGGAGAAGAAGACCCAATACTTCAAGCGTGC
    >rpl-8
    GCTCTCCAGATCCTCCGTCTTCGTCAGATCAA
    >rpl-8
    AAGTTCAACATCATCTGTCTTGAGGA"""
    
    results = {}
    
    lines = input_.splitlines()
    for i, j in zip(lines[::2], lines[1::2]):
        results.setdefault(i, []).append(j)
    
    for i, j in results.items():
        print(i)
        print("\n".join(j))
    

    >rpl-7
    ATGGCTCCAAC
    AAGAAAGTGCCACAGGTTCCAGAAAC
    >rpl-8
    AAGAACAAGGAGAAGAAGACCCAATACTTCAAGCGTGC
    GCTCTCCAGATCCTCCGTCTTCGTCAGATCAA
    AAGTTCAACATCATCTGTCTTGAGGA
    

    【讨论】:

      猜你喜欢
      • 2012-12-19
      • 2022-12-16
      • 1970-01-01
      • 2017-12-12
      • 2021-02-09
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多