序列对象

生物序列可以说是生物信息学的中心对象,在本章中,我们将介绍处理序列的Biopython机制,即 Seq object.章  顺序注释对象 将介绍相关 SeqRecord 对象,它将序列信息与任何注释结合在一起,在第章中再次使用  序列输入/输出 用于序列输入/输出。

序列本质上是字母串,例如 AGTACACTGGT ,这似乎非常自然,因为这是生物文件格式中看到序列的最常见方式。

之间最重要的区别 Seq 对象和标准Python字符串是它们有不同的方法。虽然 Seq 对象支持许多与普通字符串相同的方法,其 translate() 方法因进行生物翻译而有所不同,并且还有其他生物相关方法,例如 reverse_complement() .

序列的作用就像字符串

在大多数情况下,我们可以像对待普通Python字符串一样处理Seq对象,例如获取长度或迭代元素:

>>> from Bio.Seq import Seq
>>> my_seq = Seq("GATCG")
>>> for index, letter in enumerate(my_seq):
...     print("%i %s" % (index, letter))
...
0 G
1 A
2 T
3 C
4 G
>>> print(len(my_seq))
5

您可以以与字符串相同的方式访问序列的元素(但请记住,Python从零开始计数!):

>>> print(my_seq[0])  # first letter
G
>>> print(my_seq[2])  # third letter
T
>>> print(my_seq[-1])  # last letter
G

Seq 对象具有 .count() 方法,就像字符串一样。请注意,这意味着就像Python字符串一样,这给出了 non-overlapping 计数:

>>> from Bio.Seq import Seq
>>> "AAAA".count("AA")
2
>>> Seq("AAAA").count("AA")
2

对于某些生物用途,您实际上可能需要重叠计数(即 \(3\) 在这个微不足道的例子中)。当搜索单个字母时,这没有什么区别:

>>> from Bio.Seq import Seq
>>> my_seq = Seq("GATCGATGGGCCTATATAGGATCGAAAATCGC")
>>> len(my_seq)
32
>>> my_seq.count("G")
9
>>> 100 * (my_seq.count("G") + my_seq.count("C")) / len(my_seq)
46.875

虽然您可以使用上面的代码片段来计算GC%,但请注意 Bio.SeqUtils 模块已经构建了多个GC功能。例如:

>>> from Bio.Seq import Seq
>>> from Bio.SeqUtils import gc_fraction
>>> my_seq = Seq("GATCGATGGGCCTATATAGGATCGAAAATCGC")
>>> gc_fraction(my_seq)
0.46875

请注意,使用 Bio.SeqUtils.gc_fraction() 函数应该自动处理混合大小写序列和表示G或C的模糊核苷酸S。

另请注意,就像普通的Python字符串一样, Seq 对象在某种程度上是“只读”的。如果您需要编辑序列,例如模拟点突变,请查看部分  MutableSeq对象 下面谈谈 MutableSeq object.

切片序列

一个更复杂的例子,让我们获取序列的一部分:

>>> from Bio.Seq import Seq
>>> my_seq = Seq("GATCGATGGGCCTATATAGGATCGAAAATCGC")
>>> my_seq[4:12]
Seq('GATGGGCC')

请注意,“Seq”对象遵循Python字符串的通常索引约定,序列的第一个元素编号为0。当您执行切片时,第一个项目被包括(即本例中的4),而最后一个项目被排除(本例中的12)。

也像Python字符串一样,您可以使用start,stop和 stride (the步长,默认值为1)。例如,我们可以得到这个DNA序列的第一,第二和第三密码子位置:

>>> my_seq[0::3]
Seq('GCTGTAGTAAG')
>>> my_seq[1::3]
Seq('AGGCATGCATC')
>>> my_seq[2::3]
Seq('TAGCTAAGAC')

您可能在Python字符串中见过的另一个跨度技巧是使用-1跨度来颠倒字符串。您可以使用 Seq 对象也:

>>> my_seq[::-1]
Seq('CGCTAAAAGCTAGGATATATCCGGGTAGCTAG')

将Seq对象转换为字符串

如果您确实只需要一个普通字符串,例如写入文件或插入数据库,那么这非常容易获得:

>>> str(my_seq)
'GATCGATGGGCCTATATAGGATCGAAAATCGC'

因为咨询 str()Seq 对象将完整序列作为字符串返回,则实际上通常不必显式执行此转换。Python在打印函数中自动执行此操作:

>>> print(my_seq)
GATCGATGGGCCTATATAGGATCGAAAATCGC

您还可以使用 Seq 直接用一个对象 %s 使用Python字符串格式或插值运算符时的占位符 (% ):

>>> fasta_format_string = ">Name\n%s\n" % my_seq
>>> print(fasta_format_string)
>Name
GATCGATGGGCCTATATAGGATCGAAAATCGC

这行代码构造了一个简单的FASTA格式记录(无需担心行包装)。部分  format方法 描述了一种从 SeqRecord 对象,而阅读和编写FASTA格式序列文件的更一般主题则在第一章中介绍  序列输入/输出 .

连接或添加序列

Seq 可以通过添加对象来连接对象:

>>> from Bio.Seq import Seq
>>> seq1 = Seq("ACGT")
>>> seq2 = Seq("AACCGG")
>>> seq1 + seq2
Seq('ACGTAACCGG')

Biopython不会检查序列内容,并且如果例如您连接蛋白质序列和DNA序列(这可能是一个错误),也不会引发异常:

>>> from Bio.Seq import Seq
>>> protein_seq = Seq("EVRNAK")
>>> dna_seq = Seq("ACGT")
>>> protein_seq + dna_seq
Seq('EVRNAKACGT')

您可能经常有许多序列需要添加在一起,这可以通过这样的for循环来完成:

>>> from Bio.Seq import Seq
>>> list_of_seqs = [Seq("ACGT"), Seq("AACC"), Seq("GGTT")]
>>> concatenated = Seq("")
>>> for s in list_of_seqs:
...     concatenated += s
...
>>> concatenated
Seq('ACGTAACCGGTT')

就像Python字符串一样,Biopython Seq 也有一个 .join 方法:

>>> from Bio.Seq import Seq
>>> contigs = [Seq("ATG"), Seq("ATCCCG"), Seq("TTGCA")]
>>> spacer = Seq("N" * 10)
>>> spacer.join(contigs)
Seq('ATGNNNNNNNNNNATCCCGNNNNNNNNNNTTGCA')

更改案例

Python字符串非常有用 upperlower 改变案件的方法。例如,

>>> from Bio.Seq import Seq
>>> dna_seq = Seq("acgtACGT")
>>> dna_seq
Seq('acgtACGT')
>>> dna_seq.upper()
Seq('ACGTACGT')
>>> dna_seq.lower()
Seq('acgtacgt')

这些对于执行不区分大小写的匹配很有用:

>>> "GTAC" in dna_seq
False
>>> "GTAC" in dna_seq.upper()
True

核苷序列和(反向)互补序列

对于碱基序列,您可以轻松获得碱基序列的互补序列或反向互补序列 Seq 对象使用其内置方法:

>>> from Bio.Seq import Seq
>>> my_seq = Seq("GATCGATGGGCCTATATAGGATCGAAAATCGC")
>>> my_seq
Seq('GATCGATGGGCCTATATAGGATCGAAAATCGC')
>>> my_seq.complement()
Seq('CTAGCTACCCGGATATATCCTAGCTTTTAGCG')
>>> my_seq.reverse_complement()
Seq('GCGATTTTCGATCCTATATAGGCCCATCGATC')

如前所述,一种简单的方法来扭转 Seq 对象(或Python字符串)通过-1步对其进行切片:

>>> my_seq[::-1]
Seq('CGCTAAAAGCTAGGATATATCCGGGTAGCTAG')

如果你不小心尝试做一些奇怪的事情,例如获取蛋白质序列的(反向)互补序列,那么结果在生物学上毫无意义:

>>> from Bio.Seq import Seq
>>> protein_seq = Seq("EVRNAK")
>>> protein_seq.complement()
Seq('EBYNTM')

这里的字母“E”不是有效的IUPAC模糊性代码,因此没有被补充。然而,“V”意味着“A”、“C”或“G”,并有补语“B”等。

部分中的示例  将序列文件转换为反向互补序列 结合 Seq 对象反向补法 Bio.SeqIO 用于序列输入/输出。

转录

在谈论转录之前,我想尝试澄清串问题。考虑以下编码短肽的双链DNA片段:

\[\begin{split}\begin{gathered} \text{DNA coding strand (aka Crick strand, strand } +1 \text{)} \\ \text{5'} \qquad \texttt{ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG} \qquad \text{3'} \\ \texttt{|||||||||||||||||||||||||||||||||||||||} \\ \text{3'} \qquad \texttt{TACCGGTAACATTACCCGGCGACTTTCCCACGGGCTATC} \qquad \text{5'} \\ \text{DNA template strand (aka Watson strand, strand } -1 \text{)} \end{gathered}\end{split}\]

该DNA序列的转录产生以下RNA序列:

\[\begin{split}\begin{gathered} \text{5'} \qquad \texttt{AUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAG} \qquad \text{3'} \\ \text{Single-stranded messenger RNA} \end{gathered}\end{split}\]

实际的生物转录过程从模板链开始,进行反向互补(TMAG \(\rightarrow\) CUGA)提供mRNA。然而,在Biopython和一般生物信息学中,我们通常直接使用编码链,因为这意味着我们只需通过切换T就可以获得mRNA序列 \(\rightarrow\) 联合

现在让我们开始在Biopython中进行转录。首先,让我们创建 Seq 编码和模板DNA链的对象:

>>> from Bio.Seq import Seq
>>> coding_dna = Seq("ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG")
>>> coding_dna
Seq('ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG')
>>> template_dna = coding_dna.reverse_complement()
>>> template_dna
Seq('CTATCGGGCACCCTTTCAGCGGCCCATTACAATGGCCAT')

这些应该与上图相匹配-记住,按照惯例,通常从5 '到3 '方向读取碱基序列,而在图中,模板链显示相反。

现在让我们使用 Seq 对象内置 transcribe 方法:

>>> coding_dna
Seq('ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG')
>>> messenger_rna = coding_dna.transcribe()
>>> messenger_rna
Seq('AUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAG')

正如你所看到的,这只是用U代替T。

如果你确实想从模板链开始进行真正的生物转录,那么这就变成了一个两步的过程:

>>> template_dna.reverse_complement().transcribe()
Seq('AUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAG')

Seq 对象还包括一种从mRNA到DNA编码链的逆转录方法。同样,这是一个简单的U \(\rightarrow\) T替换:

>>> from Bio.Seq import Seq
>>> messenger_rna = Seq("AUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAG")
>>> messenger_rna
Seq('AUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAG')
>>> messenger_rna.back_transcribe()
Seq('ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG')

Note:Seq 对象的 transcribeback_transcribe Biopython 1.49中添加了方法。对于较旧的版本,您必须使用 Bio.Seq 改为模块的功能,请参阅部分  直接使用字符串 .

翻译

坚持上面转录部分讨论的相同例子,现在让我们将该mRNA翻译成相应的蛋白质序列-再次利用其中一个 Seq 对象的生物学方法:

>>> from Bio.Seq import Seq
>>> messenger_rna = Seq("AUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAG")
>>> messenger_rna
Seq('AUGGCCAUUGUAAUGGGCCGCUGAAAGGGUGCCCGAUAG')
>>> messenger_rna.translate()
Seq('MAIVMGR*KGAR*')

您还可以直接从编码链DNA序列翻译:

>>> from Bio.Seq import Seq
>>> coding_dna = Seq("ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG")
>>> coding_dna
Seq('ATGGCCATTGTAATGGGCCGCTGAAAGGGTGCCCGATAG')
>>> coding_dna.translate()
Seq('MAIVMGR*KGAR*')

你应该注意到在上面的蛋白质序列中,除了终止符,还有一个内部终止符。这是一个故意选择的例子,因为它提供了一个借口来谈论一些可选的参数,包括不同的翻译表(遗传密码)。

Biopython中可用的翻译表基于这些 from the NCBI (see本教程的下一部分)。默认情况下,翻译将使用 standard 遗传密码(NCBI表id 1)。假设我们正在处理线粒体序列。我们需要告诉翻译函数使用相关的遗传密码:

>>> coding_dna.translate(table="Vertebrate Mitochondrial")
Seq('MAIVMGRWKGAR*')

您还可以使用NCBI表号指定表,该表号较短,通常包含在班克文件的功能注释中:

>>> coding_dna.translate(table=2)
Seq('MAIVMGRWKGAR*')

现在,您可能想将这些核苷翻译到第一个框内终止密码子,然后停止(就像自然界中发生的那样):

>>> coding_dna.translate()
Seq('MAIVMGR*KGAR*')
>>> coding_dna.translate(to_stop=True)
Seq('MAIVMGR')
>>> coding_dna.translate(table=2)
Seq('MAIVMGRWKGAR*')
>>> coding_dna.translate(table=2, to_stop=True)
Seq('MAIVMGRWKGAR')

请注意,当您使用 to_stop 参数,终止密码子本身不会被翻译-并且终止符号不包括在蛋白质序列的末尾。

如果您不喜欢默认星号,您甚至可以指定停止符号:

>>> coding_dna.translate(table=2, stop_symbol="@")
Seq('MAIVMGRWKGAR@')

现在,假设你有一个完整的编码序列CDS,也就是说一个碱基序列(例如mRNA -在任何拼接后),它是密码子的总数(即长度是三的倍数),以起始密码子开始,以终止密码子结束,并且没有内部框内终止密码子。一般来说,给定完整的CDS,默认翻译方法将执行您想要的操作(也许使用 to_stop 选项)。然而,如果您的序列使用非标准起始密码子怎么办?这种情况在细菌中经常发生-例如基因yaaX E. coli K12:

>>> from Bio.Seq import Seq
>>> gene = Seq(
...     "GTGAAAAAGATGCAATCTATCGTACTCGCACTTTCCCTGGTTCTGGTCGCTCCCATGGCA"
...     "GCACAGGCTGCGGAAATTACGTTAGTCCCGTCAGTAAAATTACAGATAGGCGATCGTGAT"
...     "AATCGTGGCTATTACTGGGATGGAGGTCACTGGCGCGACCACGGCTGGTGGAAACAACAT"
...     "TATGAATGGCGAGGCAATCGCTGGCACCTACACGGACCGCCGCCACCGCCGCGCCACCAT"
...     "AAGAAAGCTCCTCATGATCATCACGGCGGTCATGGTCCAGGCAAACATCACCGCTAA"
... )
>>> gene.translate(table="Bacterial")
Seq('VKKMQSIVLALSLVLVAPMAAQAAEITLVPSVKLQIGDRDNRGYYWDGGHWRDH...HR*',
ProteinAlpabet())
>>> gene.translate(table="Bacterial", to_stop=True)
Seq('VKKMQSIVLALSLVLVAPMAAQAAEITLVPSVKLQIGDRDNRGYYWDGGHWRDH...HHR')

在细菌遗传密码中 GTG 是一个有效的起始密码子,而且它确实如此 normally 编码Val,如果用作起始密码子,则应翻译为甲硫素。如果您告诉Biopython您的序列是完整的CDS,就会发生这种情况:

>>> gene.translate(table="Bacterial", cds=True)
Seq('MKKMQSIVLALSLVLVAPMAAQAAEITLVPSVKLQIGDRDNRGYYWDGGHWRDH...HHR')

除了告诉Biopython将替代起始密码子翻译为甲硫氨酸外,使用此选项还可以确保您的序列确实是有效的CDS(如果不是,则会得到异常)。

部分中的示例  翻译CDS条目的FASTA文件 结合 Seq 对象的翻译方法 Bio.SeqIO 用于序列输入/输出。

转换表

在前面的部分中,我们讨论了 Seq 对象翻译方法(并在 Bio.Seq 模块-请参阅部分  直接使用字符串 ).在内部,这些使用从ftp://ftp.ncbi.nlm.nih.gov/entrez/misc/data/gc.prt上的NCBI信息派生的密码子表对象,也以更可读的布局显示在https://www.ncbi.nlm.nih.gov/Taxonomy/Utils/wprintgc.cgi上。

与之前一样,让我们只关注两个选择:标准翻译表和脊椎动物线粒体DNA的翻译表。

>>> from Bio.Data import CodonTable
>>> standard_table = CodonTable.unambiguous_dna_by_name["Standard"]
>>> mito_table = CodonTable.unambiguous_dna_by_name["Vertebrate Mitochondrial"]

或者,这些表分别标记有ID号1和2:

>>> from Bio.Data import CodonTable
>>> standard_table = CodonTable.unambiguous_dna_by_id[1]
>>> mito_table = CodonTable.unambiguous_dna_by_id[2]

您可以通过打印实际表格来直观地比较它们:

>>> print(standard_table)
Table 1 Standard, SGC0

  |  T      |  C      |  A      |  G      |
--+---------+---------+---------+---------+--
T | TTT F   | TCT S   | TAT Y   | TGT C   | T
T | TTC F   | TCC S   | TAC Y   | TGC C   | C
T | TTA L   | TCA S   | TAA Stop| TGA Stop| A
T | TTG L(s)| TCG S   | TAG Stop| TGG W   | G
--+---------+---------+---------+---------+--
C | CTT L   | CCT P   | CAT H   | CGT R   | T
C | CTC L   | CCC P   | CAC H   | CGC R   | C
C | CTA L   | CCA P   | CAA Q   | CGA R   | A
C | CTG L(s)| CCG P   | CAG Q   | CGG R   | G
--+---------+---------+---------+---------+--
A | ATT I   | ACT T   | AAT N   | AGT S   | T
A | ATC I   | ACC T   | AAC N   | AGC S   | C
A | ATA I   | ACA T   | AAA K   | AGA R   | A
A | ATG M(s)| ACG T   | AAG K   | AGG R   | G
--+---------+---------+---------+---------+--
G | GTT V   | GCT A   | GAT D   | GGT G   | T
G | GTC V   | GCC A   | GAC D   | GGC G   | C
G | GTA V   | GCA A   | GAA E   | GGA G   | A
G | GTG V   | GCG A   | GAG E   | GGG G   | G
--+---------+---------+---------+---------+--

以及:

>>> print(mito_table)
Table 2 Vertebrate Mitochondrial, SGC1

  |  T      |  C      |  A      |  G      |
--+---------+---------+---------+---------+--
T | TTT F   | TCT S   | TAT Y   | TGT C   | T
T | TTC F   | TCC S   | TAC Y   | TGC C   | C
T | TTA L   | TCA S   | TAA Stop| TGA W   | A
T | TTG L   | TCG S   | TAG Stop| TGG W   | G
--+---------+---------+---------+---------+--
C | CTT L   | CCT P   | CAT H   | CGT R   | T
C | CTC L   | CCC P   | CAC H   | CGC R   | C
C | CTA L   | CCA P   | CAA Q   | CGA R   | A
C | CTG L   | CCG P   | CAG Q   | CGG R   | G
--+---------+---------+---------+---------+--
A | ATT I(s)| ACT T   | AAT N   | AGT S   | T
A | ATC I(s)| ACC T   | AAC N   | AGC S   | C
A | ATA M(s)| ACA T   | AAA K   | AGA Stop| A
A | ATG M(s)| ACG T   | AAG K   | AGG Stop| G
--+---------+---------+---------+---------+--
G | GTT V   | GCT A   | GAT D   | GGT G   | T
G | GTC V   | GCC A   | GAC D   | GGC G   | C
G | GTA V   | GCA A   | GAA E   | GGA G   | A
G | GTG V(s)| GCG A   | GAG E   | GGG G   | G
--+---------+---------+---------+---------+--

您可能会发现以下属性很有用-例如,如果您正在尝试自己的基因查找:

>>> mito_table.stop_codons
['TAA', 'TAG', 'AGA', 'AGG']
>>> mito_table.start_codons
['ATT', 'ATC', 'ATA', 'ATG', 'GTG']
>>> mito_table.forward_table["ACG"]
'T'

比较Seq对象

序列比较实际上是一个非常复杂的话题,没有简单的方法来判断两个序列是否相等。基本问题是序列中字母的含义取决于上下文--字母“A”可能是DNA、RNA或蛋白质序列的一部分。Biopython可以跟踪分子类型,因此比较两个 Seq 对象也可以考虑这个。

DNA片段“ACG”和RNA片段“ACG”应该相等吗?那ACG肽呢还是Python字符串“ACG”?在日常使用中,您的序列通常都是相同类型的(所有DNA,所有RNA或所有蛋白质)。好吧,从Biopython 1.65开始,序列比较只查看序列,并像Python字符串一样进行比较。

>>> from Bio.Seq import Seq
>>> seq1 = Seq("ACGT")
>>> "ACGT" == seq1
True
>>> seq1 == "ACGT"
True

作为其扩展,在Python字典中使用序列对象作为键相当于使用序列作为键的纯字符串。另见章节  将Seq对象转换为字符串 .

序列内容未知的序列

在某些情况下,序列的长度可能是已知的,但不知道构成它的实际字母。例如,基因库和EmbL文件可能仅通过其配置信息来代表基因组DNA序列,而不明确指定序列内容。此类序列可以通过创建 Seq 带有参数的对象 None ,后面是序列长度:

>>> from Bio.Seq import Seq
>>> unknown_seq = Seq(None, 10)

Seq 由此创建的对象具有明确定义的长度。然而,任何访问序列内容的尝试都会引发 UndefinedSequenceError :

>>> unknown_seq
Seq(None, length=10)
>>> len(unknown_seq)
10
>>> print(unknown_seq)
Traceback (most recent call last):
...
Bio.Seq.UndefinedSequenceError: Sequence content is undefined
>>>

具有部分定义序列内容的序列

有时,序列内容仅为序列的部分定义,而在其他地方未定义。例如,下面的APM(多重比对格式)文件摘录显示了人类、黑猩猩、猕猴、小鼠、大鼠、狗和负鼠基因组序列的比对:

s hg38.chr7     117512683 36 + 159345973 TTGAAAACCTGAATGTGAGAGTCAGTCAAGGATAGT
s panTro4.chr7  119000876 36 + 161824586 TTGAAAACCTGAATGTGAGAGTCACTCAAGGATAGT
s rheMac3.chr3  156330991 36 + 198365852 CTGAAATCCTGAATGTGAGAGTCAATCAAGGATGGT
s mm10.chr6      18207101 36 + 149736546 CTGAAAACCTAAGTAGGAGAATCAACTAAGGATAAT
s rn5.chr4       42326848 36 + 248343840 CTGAAAACCTAAGTAGGAGAGACAGTTAAAGATAAT
s canFam3.chr14  56325207 36 +  60966679 TTGAAAAACTGATTATTAGAGTCAATTAAGGATAGT
s monDom5.chr8  173163865 36 + 312544902 TTAAGAAACTGGAAATGAGGGTTGAATGACAAACTT

在每一行中,第一个数字表示染色体上比对序列的开始位置(以零为起点的坐标),然后是比对序列的大小、链、完整染色体的大小和比对序列。

A Seq 可以使用 data 参数,其中键是已知序列段的开始坐标,值是相应的序列内容。例如,对于第一个序列,我们将使用

>>> from Bio.Seq import Seq
>>> seq = Seq({117512683: "TTGAAAACCTGAATGTGAGAGTCAGTCAAGGATAGT"}, length=159345973)

从部分定义的序列中提取子序列可能会返回完全定义的序列、未定义的序列或部分定义的序列,具体取决于坐标:

>>> seq[1000:1020]
Seq(None, length=20)
>>> seq[117512690:117512700]
Seq('CCTGAATGTG')
>>> seq[117512670:117512690]
Seq({13: 'TTGAAAA'}, length=20)
>>> seq[117512700:]
Seq({0: 'AGAGTCAGTCAAGGATAGT'}, length=41833273)

如果至少有一个序列部分或完全未定义,则也可以通过附加序列来创建部分定义的序列:

>>> seq = Seq("ACGT")
>>> undefined_seq = Seq(None, length=10)
>>> seq + undefined_seq + seq
Seq({0: 'ACGT', 14: 'ACGT'}, length=18)

MutableSeq对象

就像普通的Python字符串一样, Seq 对象是“只读”的,或者用Python术语来说是不可变的。除了想要 Seq 对象像字符串一样发挥作用,这也是一个有用的默认值,因为在许多生物应用中,您希望确保不会改变序列数据:

>>> from Bio.Seq import Seq
>>> my_seq = Seq("GCCATTGTAATGGGCCGCTGAAAGGGTGCCCGA")

观察如果您尝试编辑序列会发生什么:

>>> my_seq[5] = "G"
Traceback (most recent call last):
...
TypeError: 'Seq' object does not support item assignment

但是,您可以将其转换为可变序列( MutableSeq 对象)并用它做几乎任何您想做的事情:

>>> from Bio.Seq import MutableSeq
>>> mutable_seq = MutableSeq(my_seq)
>>> mutable_seq
MutableSeq('GCCATTGTAATGGGCCGCTGAAAGGGTGCCCGA')

或者,您可以创建一个 MutableSeq 直接从字符串中提取对象:

>>> from Bio.Seq import MutableSeq
>>> mutable_seq = MutableSeq("GCCATTGTAATGGGCCGCTGAAAGGGTGCCCGA")

无论哪种方式都将为您提供一个可以更改的序列对象:

>>> mutable_seq
MutableSeq('GCCATTGTAATGGGCCGCTGAAAGGGTGCCCGA')
>>> mutable_seq[5] = "C"
>>> mutable_seq
MutableSeq('GCCATCGTAATGGGCCGCTGAAAGGGTGCCCGA')
>>> mutable_seq.remove("T")
>>> mutable_seq
MutableSeq('GCCACGTAATGGGCCGCTGAAAGGGTGCCCGA')
>>> mutable_seq.reverse()
>>> mutable_seq
MutableSeq('AGCCCGTGGGAAAGTCGCCGGGTAATGCACCG')

注意到 MutableSeq 对象的 reverse() 方法,就像 reverse() Python列表的方法,将序列就地颠倒。

Python中可变对象和不可变对象之间的一个重要技术差异意味着不能使用 MutableSeq 对象作为字典键,但您可以使用Python字符串或 Seq 以这种方式对象。

一旦您完成编辑您的 MutableSeq 对象,很容易回到只读 Seq 如果您需要,对象:

>>> from Bio.Seq import Seq
>>> new_seq = Seq(mutable_seq)
>>> new_seq
Seq('AGCCCGTGGGAAAGTCGCCGGGTAATGCACCG')

您还可以从 MutableSeq 物体就像来自一个 Seq 对象(部分  将Seq对象转换为字符串 ).

寻找根源

序列对象具有 find , rfind , index ,而且 rindex 与纯字符串对象上的相应方法执行相同功能的方法。唯一的区别是子序列可以是字符串 (str ), bytes , bytearray , Seq ,或者 MutableSeq 对象:

>>> from Bio.Seq import Seq, MutableSeq
>>> seq = Seq("GCCATTGTAATGGGCCGCTGAAAGGGTGCCCGA")
>>> seq.index("ATGGGCCGC")
9
>>> seq.index(b"ATGGGCCGC")
9
>>> seq.index(bytearray(b"ATGGGCCGC"))
9
>>> seq.index(Seq("ATGGGCCGC"))
9
>>> seq.index(MutableSeq("ATGGGCCGC"))
9

A ValueError 如果找不到子序列,则引发:

>>> seq.index("ACTG")
Traceback (most recent call last):
...
ValueError: ...

find 如果没有找到子序列,则方法返回-1:

>>> seq.find("ACTG")
-1

的方法 rfindrindex 从序列右侧开始搜索子序列:

>>> seq.find("CC")
1
>>> seq.rfind("CC")
29

使用 search 同时搜索多个子序列的方法。此方法返回迭代器:

>>> for index, sub in seq.search(["CC", "GGG", "CC"]):
...     print(index, sub)
...
1 CC
11 GGG
14 CC
23 GGG
28 CC
29 CC

search 方法还采用纯字符串, bytes , bytearray , Seq ,而且 MutableSeq 对象作为子序列;相同的子序列只报告一次,如上面的例子所示。

直接使用字符串

为了结束这一章,对于那些你谁 really 不想使用序列对象(或者更喜欢函数式编程风格而不是面向对象的编程风格),其中有模块级函数 Bio.Seq 将接受纯Python字符串, Seq 对象或 MutableSeq 对象:

>>> from Bio.Seq import reverse_complement, transcribe, back_transcribe, translate
>>> my_string = "GCTGTTATGGGTCGTTGGAAGGGTGGTCGTGCTGCTGGTTAG"
>>> reverse_complement(my_string)
'CTAACCAGCAGCACGACCACCCTTCCAACGACCCATAACAGC'
>>> transcribe(my_string)
'GCUGUUAUGGGUCGUUGGAAGGGUGGUCGUGCUGCUGGUUAG'
>>> back_transcribe(my_string)
'GCTGTTATGGGTCGTTGGAAGGGTGGTCGTGCTGCTGGTTAG'
>>> translate(my_string)
'AVMGRWKGGRAAG*'

然而,我们鼓励您与 Seq 默认情况下对象。