ДНК: четыре буквы и двойная спираль
ДНК — это просто строка из четырёх букв, но с одним хитрым свойством: у неё есть «вторая копия наизнанку».
ДНК (дезоксирибонуклеиновая кислота) — молекула-носитель наследственной информации, последовательность из четырёх нуклеотидов: A (аденин), T (тимин), G (гуанин), C (цитозин).
Чтобы анализировать геном, не нужно быть химиком. Достаточно принять простую модель: ДНК — это строка над алфавитом из четырёх символов. Всё остальное (длина, состав, поиск, мутации) — операции над строкой. Этот урок даёт тот минимум биологии, который реально влияет на код.
Алфавит из четырёх букв
Нуклеотиды бывают двух химических классов, и это пригодится позже:
| Буква | Название | Класс |
| A | аденин | пурин |
| G | гуанин | пурин |
| C | цитозин | пиримидин |
| T | тимин | пиримидин |
Двойная спираль и комплементарность
Главная идея: ДНК состоит из двух нитей, закрученных в спираль. Нити не одинаковы — они комплементарны. Напротив A всегда стоит T, напротив G всегда стоит C (и наоборот). Эти пары держатся водородными связями: A=T (две связи), G≡C (три связи).
5'- A T G C G A T -3' <- нить 1
| | | | | | |
3'- T A C G C T A -5' <- нить 2 (комплементарная)Зачем это программисту? Комплементарность означает, что вторую нить можно вычислить из первой — информация дублируется. Именно поэтому ДНК умеет копироваться: расплести спираль, и каждая нить становится шаблоном для новой парной. И именно поэтому в коде мы постоянно строим «комплемент» строки. Это встроенная избыточность: если одна нить повреждена, клетка восстанавливает её по второй — а в наших алгоритмах та же избыточность позволяет искать гены сразу на обеих нитях, имея в руках только одну.
Сразу разведём три понятия, которые новички путают. Нуклеотид — одна буква (A, T, G или C). Пара оснований (bp, base pair) — две буквы напротив друг друга на двух нитях; в этих единицах измеряют длину геномов (геном человека — около 3,2 миллиарда пар оснований). Нить (strand) — одна из двух цепей спирали. Когда говорят «фрагмент длиной 500 bp», имеют в виду 500 пар, то есть строку из 500 букв на каждой нити. В коде мы обычно держим одну нить как строку, помня, что вторая всегда восстановима.
# Комплемент: заменяем каждую букву на её пару
pairs = {"A": "T", "T": "A", "G": "C", "C": "G"}
strand = "ATGCGAT"
complement = "".join(pairs[base] for base in strand)
print("Нить 1: ", strand)
print("Комплемент: ", complement)Вывод:
Нить 1: ATGCGAT Комплемент: TACGCTA
Направленность нитей
У каждой нити есть направление — концы называют 5' (пять-штрих) и 3' (три-штрих). Две нити антипараллельны: одна идёт 5'→3', другая 3'→5'. Это объясняет, почему позже нам понадобится не просто комплемент, а обратный комплемент (перевернуть и взять пары). Биологический «смысл» читается в направлении 5'→3'.
Как работает под капотом: правило Чаргаффа
Из комплементарности следует наблюдение Чаргаффа: в двунитевой ДНК количество A равно количеству T, а количество G равно количеству C. Проверим это на сгенерированной паре нитей.
pairs = {"A": "T", "T": "A", "G": "C", "C": "G"}
strand1 = "AATGGCCATGCGTA"
strand2 = "".join(pairs[b] for b in strand1)
full = strand1 + strand2 # обе нити вместе
print("A:", full.count("A"), " T:", full.count("T"))
print("G:", full.count("G"), " C:", full.count("C"))Вывод:
A: 7 T: 7 G: 7 C: 7
A = T и G = C — ровно правило Чаргаффа, прямое следствие парности (здесь к тому же A = T = G = C, потому что в этой паре нитей букв поровну).
Частые ошибки
- Считать, что A пара с G. Нет: A–T и G–C. Перепутанные пары — частый баг в комплементе.
- Забывать про направление. Просто комплемент и обратный комплемент — разные вещи; биологам нужен обычно второй.
- Использовать U вместо T в ДНК. U (урацил) — это про РНК, в ДНК всегда T.
Итог
- ДНК — строка над алфавитом {A, T, G, C}.
- Две нити комплементарны: A–T, G–C; вторая нить вычисляется из первой.
- Комплементарность объясняет копирование ДНК и постоянно используется в коде.
- Нити антипараллельны (5'→3' против 3'→5'), отсюда понятие обратного комплемента.