Python - 水平打印两个字符串,用 | 分隔
我遇到了一个小小的格式问题,解决起来有点棘手。我有一些很长的字符串,都是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 个回答
如果我理解得没错,这个问题是关于格式化的。我建议你看看 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--
你可以试试下面这个简单的方法,它不要求大小必须相同,不过你可以根据自己的需要进行调整。
def printSequences(seq1, seq2):
print('seq1',seq1)
print(' ','|'*max(len(seq1),len(seq2)))
print('seq2',seq2)
这里有一个适合处理长字符串的解决方案:
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个碱基对)来试的时候,结果会更合理。
注意,这个函数需要输入两个长度相同的序列,所以这只是为了在你完成所有对齐工作后,把结果打印得好看一些。
附注:通常在序列对齐中,只会为匹配的碱基显示竖线 |
。这个解决方案其实很简单,你应该能搞明白(如果有困难的话,告诉我)。