Python for Biologists

Lesson 9 of 14 · 11 min

Dictionaries and Codon Tables

A dictionary is a way to store pairs of related values so you can look one up from the other. Each pair has a key, which is the thing you search by, and a value, which is what you get back. This is a perfect match for biology, where a three-letter DNA codon maps to a single amino acid.

Creating a dictionary

You build a dictionary with curly braces, writing each pair as key colon value and separating pairs with commas. To read a value back, you write the dictionary name followed by the key in square brackets, but that crashes with a KeyError if the key is missing. The safer .get() method does the same lookup and lets you supply a fallback value for keys that are not there.

python
amino_acid_names = {
    "M": "Methionine",
    "F": "Phenylalanine",
    "G": "Glycine",
}

print(amino_acid_names["M"])
print(amino_acid_names.get("F"))
print(amino_acid_names.get("Z", "unknown"))
Methionine
Phenylalanine
unknown

Building a codon table

python
codon_table = {
    "ATG": "M",
    "TTT": "F",
    "GGA": "G",
    "TAA": "*",
}

for codon, amino_acid in codon_table.items():
    print(codon, "codes for", amino_acid)
ATG codes for M
TTT codes for F
GGA codes for G
TAA codes for *

The .items() method used above hands you both the key and the value on each pass of the loop, which is why we wrote two loop variables, codon and amino_acid. Here the amino acids use one-letter codes, and the asterisk marks a stop codon, the signal that ends translation. Next we translate a real sequence by walking it three bases at a time. In the cell the ribosome actually reads messenger RNA that is copied from this DNA coding strand, but the triplets line up one-to-one, so reading the DNA in non-overlapping three-base steps gives the same codons. We start with an empty protein string and glue each amino acid onto the end, and codon_table.get(codon, "?") keeps a lookup miss from crashing the loop by returning a question mark instead.

python
sequence = "ATGTTTGGATAA"
protein = ""

for i in range(0, len(sequence), 3):
    codon = sequence[i:i + 3]
    amino_acid = codon_table.get(codon, "?")
    protein = protein + amino_acid

print(protein)
MFG*

Try it yourself: range(0, len(sequence), 3) counts 0, 3, 6, 9, and sequence[i:i + 3] slices out one codon at each step. Add two more entries to codon_table, for example "GGG": "G" and "AAA": "K", then change sequence to "ATGAAAGGGTAA" and rerun. What protein string do you predict before you run it?