如何将字符串分成相等大小的部分?

问题描述

我有一个包含核苷酸序列的字符串。该字符串长1191个核苷酸。

如何以每行只有100个核苷酸的格式打印序列?现在,我已经对其进行了硬编码,但是我希望它适用于任何字符串的核苷酸。这是我现在拥有的代码

def printinfasta(SeqName,Sequence,SeqDescription):
    print(SeqName + " " + SeqDescription)
    #how do I make sure to only have 100 nucleotides per line?
    print(Sequence[0:100])
    print(Sequence[100:200])
    print(Sequence[200:300])
    print(Sequence[400:500])
    print(Sequence[500:600])
    print(Sequence[600:700])
    print(Sequence[700:800])
    print(Sequence[800:900])
    print(Sequence[900:1000])
    print(Sequence[1000:1100])
    print(Sequence[1100:1191])
printinfasta(SeqName,SeqDescription)
Sequence = "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAATCCATAAATCCCTAAAACCATAATCCTAAATCCCTTAATTCCTAAATCCCTAATACTTAGACCCTAATCTTTAGTTCCTAGACCCTAATCTTTAGTTCCTAGACCCTAAATCCATAATCCTTAATTCCTAAATTCCTAAATCCCTAATACTAAATCTCTAAATCCCTAGCAATTTTCAAGTTTTGCTTGATTGTTGTAGGATGGTCCTTTCTCTTGTTTCTTCTCTGTGTTGTTGAGATTAGTTTGTTTAGGTTTGATAGCGTTGATTTTGGCCTGCGTTTGGTGACTCATATGGTTTGATTGGAGTTTGTTTCTGGGTTTTATGGTTTTGGTTGAAGCGACATTTTTTTGTGGAATATGGTTTTTGCAAAATATTTTGTTCCGGATGAGTAATATCTACGGTGCTGCTGTGAGAATTATGCTATTGTTTT"

解决方法

您可以使用textwrap.wrap将长字符串分成字符串列表

import textwrap

seq = "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAATCCATAAATCCCTAAAACCATAATCCTAAATCCCTTAATTCCTAAATCCCTAATACTTAGACCCTAATCTTTAGTTCCTAGACCCTAATCTTTAGTTCCTAGACCCTAAATCCATAATCCTTAATTCCTAAATTCCTAAATCCCTAATACTAAATCTCTAAATCCCTAGCAATTTTCAAGTTTTGCTTGATTGTTGTAGGATGGTCCTTTCTCTTGTTTCTTCTCTGTGTTGTTGAGATTAGTTTGTTTAGGTTTGATAGCGTTGATTTTGGCCTGCGTTTGGTGACTCATATGGTTTGATTGGAGTTTGTTTCTGGGTTTTATGGTTTTGGTTGAAGCGACATTTTTTTGTGGAATATGGTTTTTGCAAAATATTTTGTTCCGGATGAGTAATATCTACGGTGCTGCTGTGAGAATTATGCTATTGTTTT"
print('\n'.join(textwrap.wrap(seq,width=100)))
,

您可以使用itertools.zip_longest和一些iter的魔法使它成为一行:

from itertools import zip_longest

sequence = "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAATCCATAAATCCCTAAAACCATAATCCTAAATCCCTTAATTCCTAAATCCCTAATACTTAGACCCTAATCTTTAGTTCCTAGACCCTAATCTTTAGTTCCTAGACCCTAAATCCATAATCCTTAATTCCTAAATTCCTAAATCCCTAATACTAAATCTCTAAATCCCTAGCAATTTTCAAGTTTTGCTTGATTGTTGTAGGATGGTCCTTTCTCTTGTTTCTTCTCTGTGTTGTTGAGATTAGTTTGTTTAGGTTTGATAGCGTTGATTTTGGCCTGCGTTTGGTGACTCATATGGTTTGATTGGAGTTTGTTTCTGGGTTTTATGGTTTTGGTTGAAGCGACATTTTTTTGTGGAATATGGTTTTTGCAAAATATTTTGTTCCGGATGAGTAATATCTACGGTGCTGCTGTGAGAATTATGCTATTGTTTT" 

output = [''.join(filter(None,s)) for s in zip_longest(*([iter(sequence)]*100))]

或者:

for s in zip_longest(*([iter(sequence)]*100)):
    print(''.join(filter(None,s)))
,

可能的解决方案是使用re模块。

import re

def splitstring(strg,leng):
    chunks = re.findall('.{1,%d}' % leng,strg)
    for i in chunks:
        print(i)


splitstring(strg = seq,leng = 100))
,

我假设您的序列为FASTA格式。在这种情况下,您可以使用任何提供FASTA序列包装实用程序的生物信息学软件包。例如,您可以使用FASTX-Toolkit。使用FASTA Formatter命令行实用程序包装FASTA序列,例如每行最多100个核苷酸:

fasta_formatter -i INFILE -o OUTFILE -w 100

您可以使用FASTX-Toolkit安装conda软件包,例如:
conda install fastx_toolkit

conda create -n fastx_toolkit fastx_toolkit

请注意,如果最终编写(简单)代码以从头开始包装FASTA序列,请记住,标题行(以>开头的行)应该被包装。仅包装顺序线。

另请参见:

Convert single line fasta to multi line fasta

,

您可以使用基于itertools.zip_longest的帮助功能。辅助函数旨在(也)处理序列不是相等部分大小的精确倍数的情况(最后一组元素比之前的元素少)。

from itertools import zip_longest


def grouper(n,iterable):
    """ s -> (s0,s1,...sn-1),(sn,sn+1,...s2n-1),(s2n,s2n+1,...s3n-1),... """
    FILLER = object()  # Value that couldn't be in data.
    for result in zip_longest(*[iter(iterable)]*n,fillvalue=FILLER):
        yield ''.join(v for v in result if v is not FILLER)


def printinfasta(SeqName,Sequence,SeqDescription):
    print(SeqName + " " + SeqDescription)
    for group in grouper(100,Sequence):
        print(group)

Sequence = "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAATCCATAAATCCCTAAAACCATAATCCTAAATCCCTTAATTCCTAAATCCCTAATACTTAGACCCTAATCTTTAGTTCCTAGACCCTAATCTTTAGTTCCTAGACCCTAAATCCATAATCCTTAATTCCTAAATTCCTAAATCCCTAATACTAAATCTCTAAATCCCTAGCAATTTTCAAGTTTTGCTTGATTGTTGTAGGATGGTCCTTTCTCTTGTTTCTTCTCTGTGTTGTTGAGATTAGTTTGTTTAGGTTTGATAGCGTTGATTTTGGCCTGCGTTTGGTGACTCATATGGTTTGATTGGAGTTTGTTTCTGGGTTTTATGGTTTTGGTTGAAGCGACATTTTTTTGTGGAATATGGTTTTTGCAAAATATTTTGTTCCGGATGAGTAATATCTACGGTGCTGCTGTGAGAATTATGCTATTGTTTT"

printinfasta('Name','Description')

样本输出:

Name Description
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
CCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAACCCTAAATCCATAAATCCCTAAAACCATAATCCTAAATCCCTTAATTCCTA
AATCCCTAATACTTAGACCCTAATCTTTAGTTCCTAGACCCTAATCTTTAGTTCCTAGACCCTAAATCCATAATCCTTAATTCCTAAATTCCTAAATCCC
TAATACTAAATCTCTAAATCCCTAGCAATTTTCAAGTTTTGCTTGATTGTTGTAGGATGGTCCTTTCTCTTGTTTCTTCTCTGTGTTGTTGAGATTAGTT
TGTTTAGGTTTGATAGCGTTGATTTTGGCCTGCGTTTGGTGACTCATATGGTTTGATTGGAGTTTGTTTCTGGGTTTTATGGTTTTGGTTGAAGCGACAT
TTTTTTGTGGAATATGGTTTTTGCAAAATATTTTGTTCCGGATGAGTAATATCTACGGTGCTGCTGTGAGAATTATGCTATTGTTTT
,

软件包cytoolz(可使用pip install cytoolz安装)提供了功能partition_all,可在此处使用:

#!/usr/bin/env python3
from cytoolz import partition_all

def printinfasta(name,seq,descr):
    header = f">{name} {descr}"
    print(header)
    print(*map("".join,partition_all(100,seq)),sep="\n")


printinfasta("test",468 * "ACGTGA","this is a test")

partition_all(100,seq))生成从seq中抽取的每个100个字母的元组,最后一个较短的字母是字母数不是100的倍数。

map("".join,...)用于将每个这样的元组中的字母分组为单个字符串。

*前面的map将其结果视为print的单独参数。