Data Structures
Python provides four built-in data structures that you will use constantly in bioinformatics. Lists store ordered sequences. Tuples store fixed records. Dictionaries map keys to values. Sets track unique items. This page covers each one with examples drawn from genomics.
A list is an ordered, mutable collection. You create one with square brackets. Lists are ideal for storing gene names, read counts, or any sequence of values.
gene_names = ["TP53", "BRCA1", "EGFR", "KRAS", "MYC"]print(gene_names)['TP53', 'BRCA1', 'EGFR', 'KRAS', 'MYC']Use len() to check how many items a list contains.
print(len(gene_names))5Indexing and slicing
Section titled “Indexing and slicing”Python uses zero-based indexing. The first element is at index 0.
print(gene_names[0])TP53Negative indices count from the end. Index -1 gives you the last element.
print(gene_names[-1])MYCSlicing extracts a sublist. The start index is included. The stop index is excluded.
print(gene_names[1:3])['BRCA1', 'EGFR']Modifying lists
Section titled “Modifying lists”Use .append() to add an item to the end of a list.
gene_names.append("PTEN")print(gene_names)['TP53', 'BRCA1', 'EGFR', 'KRAS', 'MYC', 'PTEN']Use .remove() to delete the first occurrence of a specific value.
gene_names.remove("KRAS")print(gene_names)['TP53', 'BRCA1', 'EGFR', 'MYC', 'PTEN']List comprehensions
Section titled “List comprehensions”A list comprehension builds a new list by transforming each item in an existing list. This is a common pattern for processing expression data. Here we log-transform raw counts.
import mathcounts = [100, 250, 50, 300, 75]log_counts = [math.log2(c + 1) for c in counts]print(log_counts)[6.658211482751795, 7.971543553950772, 5.672425341971495, 8.233619676759702, 6.247927513443585]You can also filter with a condition. This extracts only significant p-values.
pvalues = [0.001, 0.23, 0.04, 0.87, 0.005]significant = [p for p in pvalues if p < 0.05]print(significant)[0.001, 0.04, 0.005]Tuples
Section titled “Tuples”A tuple is like a list, but it cannot be changed after creation. This makes tuples useful for storing fixed records like a gene’s chromosomal location.
gene_location = ("BRCA1", "chr17", 43044295)print(gene_location)('BRCA1', 'chr17', 43044295)You access elements by index, just like a list.
print(gene_location[0])BRCA1Tuple unpacking lets you assign each element to a separate variable in one line.
gene, chrom, pos = gene_locationprint(f"{gene} is at {chrom}:{pos}")BRCA1 is at chr17:43044295Dictionaries
Section titled “Dictionaries”A dictionary maps keys to values. Think of it as a lookup table. In bioinformatics, you might map gene names to expression levels.
gene_expression = { "TP53": 23.5, "BRCA1": 45.2, "EGFR": 12.8, "KRAS": 67.3,}print(gene_expression){'TP53': 23.5, 'BRCA1': 45.2, 'EGFR': 12.8, 'KRAS': 67.3}Access a value by its key.
print(gene_expression["BRCA1"])45.2Add a new entry by assigning to a new key.
gene_expression["MYC"] = 34.1print(gene_expression){'TP53': 23.5, 'BRCA1': 45.2, 'EGFR': 12.8, 'KRAS': 67.3, 'MYC': 34.1}Use .keys() and .values() to extract all keys or all values.
print(list(gene_expression.keys()))['TP53', 'BRCA1', 'EGFR', 'KRAS', 'MYC']print(list(gene_expression.values()))[23.5, 45.2, 12.8, 67.3, 34.1]Use .get() to look up a key with a default value. This avoids a KeyError when the key is missing.
print(gene_expression.get("PTEN", 0.0))0.0Iterating over dictionaries
Section titled “Iterating over dictionaries”The .items() method returns each key-value pair. This is the standard way to loop over a dictionary.
for gene, expr in gene_expression.items(): print(f"{gene}: {expr}")TP53: 23.5BRCA1: 45.2EGFR: 12.8KRAS: 67.3MYC: 34.1A set is an unordered collection of unique items. Sets are powerful for comparing gene lists. For example, you can find overlapping genes between an experiment and a known pathway.
upregulated = {"TP53", "EGFR", "MYC", "PTEN"}pathway_genes = {"TP53", "BRCA1", "EGFR", "RB1"}
overlap = upregulated & pathway_genesprint(overlap){'TP53', 'EGFR'}The - operator finds items in the first set that are not in the second.
only_up = upregulated - pathway_genesprint(only_up){'PTEN', 'MYC'}The | operator combines both sets into one.
all_genes = upregulated | pathway_genesprint(all_genes){'BRCA1', 'MYC', 'PTEN', 'TP53', 'EGFR', 'RB1'}Deduplication
Section titled “Deduplication”Converting a list to a set removes duplicates. Convert back to a list if you need list behavior. Use sorted() for consistent ordering.
gene_list = ["TP53", "BRCA1", "TP53", "EGFR", "BRCA1", "TP53"]unique_genes = list(set(gene_list))print(sorted(unique_genes))['BRCA1', 'EGFR', 'TP53']Nested structures
Section titled “Nested structures”You can nest data structures inside each other. A dictionary of dictionaries is a natural way to store sample metadata.
samples = { "S1": {"condition": "control", "read_count": 25000000}, "S2": {"condition": "treated", "read_count": 31000000},}print(samples["S1"]["condition"])controlprint(samples["S2"]["read_count"])31000000Chain the keys to reach deeper values. The first key selects the sample. The second key selects the field.
Quick reference
Section titled “Quick reference”| Structure | Syntax | Ordered | Mutable | Duplicates | Use case |
|---|---|---|---|---|---|
| List | [a, b, c] |
Yes | Yes | Yes | Gene lists, expression values |
| Tuple | (a, b, c) |
Yes | No | Yes | Fixed records, coordinates |
| Dictionary | {k: v} |
Yes* | Yes | Keys: No | Lookup tables, sample metadata |
| Set | {a, b, c} |
No | Yes | No | Unique genes, overlap analysis |
*Dictionaries preserve insertion order in Python 3.7 and later.
Next steps
Section titled “Next steps”You now know the four core data structures in Python. Next, learn how to control program flow with conditionals and loops in Control Flow.