Python - 水平打印两个字符串,用 | 分隔

1 投票
3 回答
546 浏览
提问于 2025-04-28 04:05

我遇到了一个小小的格式问题,解决起来有点棘手。我有一些很长的字符串,都是DNA序列的形式。我把每个序列放到一个单独的列表里,每个字母都是列表中的一个单独的项目。因为这些序列的长度不一样,所以我在较短的那个序列后面加了几个"N"来补齐长度。

举个例子:

seq1 = ['A', 'T', 'G', 'G', 'A', 'C', 'G', 'C', 'A']
seq2 = ['A', 'T', 'G', 'G', 'C', 'T', 'G']

seq2 变成了:['A', 'T', 'G', 'G', 'C', 'T', 'G', 'N', 'N']

现在,在比较每个列表中的字母后,我得到了:

ATGG--G--

这里的"-"表示字母不匹配(包括"N")。

理想情况下,我想打印的是:

  seq1  ATGGACGCA
        |||||||||
  seq2  ATGG--G--

我一直在尝试在打印语句的末尾加上换行符和逗号,但就是搞不定。我希望能在同一行上打印出每个序列的标识符。

这是用来比较两个序列的函数:

def align_seqs(orf, query):
        orf_base = list(orf)
        query_base = list(query)

        if len(query_base) > len(orf_base):
                N = (len(query_base) - len(orf_base))
                for i in range(N):
                        orf_base.append("N")
        elif len(query_base) < len(orf_base):
                N = (len(orf_base) - len(query_base))
                for i in range(N):
                        query_base.append("N")
        align = []

        for i in range(0, len(orf_base)):
                if orf_base[i] == query_base[i]:
                        align.append(orf_base[i])
                else:
                        align.append("-")

        print ''.join(align)

目前,我只是在打印我想要打印内容的“底部”部分。

非常感谢大家的帮助。

暂无标签

3 个回答

1

如果我理解得没错,这个问题是关于格式化的。我建议你看看 str.format() 这个方法。假设你已经把你的序列转换成字符串(就像你用 seq2 作为 align 那样)。你可以试试:

seq1 = 'ATGGACGCA'
seq2 = 'ATGG--G--'

print(' seq1: {}\n       {}\n seq2: {}'.format(seq1, len(seq1)*'|', seq2))

这个方法有点小技巧,但能完成任务。format() 方法的参数会按照顺序替换给定字符串中的 {}。我得到的结果是:

 seq1: ATGGACGCA
       |||||||||
 seq2: ATGG--G--
1

你可以试试下面这个简单的方法,它不要求大小必须相同,不过你可以根据自己的需要进行调整。

def printSequences(seq1, seq2):
    print('seq1',seq1)
    print('    ','|'*max(len(seq1),len(seq2)))
    print('seq2',seq2)
1

这里有一个适合处理长字符串的解决方案:

s1 = 'ATAAGGATAAGGATAAGGATAAGGATAAGGATAAGGATAAGGATAAGGATAAGGATAAGG'
s2 = 'A-AAGGA-AAGGA-AAGGA-AAGGA-AAGGA-AAGGA-AAGGA-AAGGA-AAGGA-AAGG'

#assumes both sequences are of same length (post-alignment)
def print_align(seq1, seq2, length):
    while len(seq1) > 0:
        print "seq1: " + seq1[:length-6]
        print "      " + '|'*len(seq1[:length-6])
        print "seq2: " + seq2[:length-6] + "\n"
        seq1 = seq1[length-6:]
        seq2 = seq2[length-6:]

print_align(s1, s2, 30)

输出结果是:

seq1: ATAAGGATAAGGATAAGGATAAGG
      ||||||||||||||||||||||||
seq2: A-AAGGA-AAGGA-AAGGA-AAGG

seq1: ATAAGGATAAGGATAAGGATAAGG
      ||||||||||||||||||||||||
seq2: A-AAGGA-AAGGA-AAGGA-AAGG

seq1: ATAAGGATAAGG
      ||||||||||||
seq2: A-AAGGA-AAGG

我相信这就是你想要的。你可以调整 length 参数,以便让每行显示得更合适(每行在达到这个参数指定的长度后就会被截断)。比如,如果我调用 print_align(s1, s2, 39),我得到的结果是:

seq1: ATAAGGATAAGGATAAGGATAAGGATAAGGATA
      |||||||||||||||||||||||||||||||||
seq2: A-AAGGA-AAGGA-AAGGA-AAGGA-AAGGA-A

seq1: AGGATAAGGATAAGGATAAGGATAAGG
      |||||||||||||||||||||||||||
seq2: AGGA-AAGGA-AAGGA-AAGGA-AAGG

当你用很大的序列(超过1000个碱基对)来试的时候,结果会更合理。

注意,这个函数需要输入两个长度相同的序列,所以这只是为了在你完成所有对齐工作后,把结果打印得好看一些。

附注:通常在序列对齐中,只会为匹配的碱基显示竖线 |。这个解决方案其实很简单,你应该能搞明白(如果有困难的话,告诉我)。

撰写回答