当前位置:首页>python>Python学习 | 05 条件判断与循环

Python学习 | 05 条件判断与循环

  • 2026-10-10 14:47:55
Python学习 | 05 条件判断与循环

前四课我们一直在建立 Python 的“对象和数据结构”:

str    → 一条序列list   → 一批对象tuple  → 一组固定数据dict   → key → valueset    → unique elements

到现在为止,我们大多是在手动操作一个对象。

这一课加入两个能力:

if   → 根据条件决定做什么for  → 对一批对象重复做什么

1. if:根据条件决定是否执行代码

1.1 if / elif / else

例如根据 GC content 做简单判断:

gc_content = 0.62if gc_content > 0.6:    print(”High GC”)

基本结构是:

if condition:    code

这里最需要注意的是两个东西:

:缩进

Python 不使用 R 的 {}:

if (gc_content > 0.6) {    print(”High GC”)}

而是使用:

if gc_content > 0.6:    print(”High GC”)

缩进本身就是代码结构的一部分。

gc_content = 0.52if gc_content > 0.6:    print(”High GC”)elif gc_content >= 0.4:    print(”Medium GC”)else:    print(”Low GC”)

1.2 在条件中组合多个判断

seq = ”ATGCGTAA”if seq.startswith(”ATG”) and seq.endswith(”TAA”):    print(”Stars with ATG and ends with TAA”)

如果只需要满足其中一个条件:

stop_codon = ”TAG”if stop_codon == ”TAA” or stop_codon == ”TAG” or stop_codon == ”TGA”:    print(”Stop codon”)

后面学到 set 之后,其实有一个更清晰的写法:

stop_codons = {”TAA”, ”TAG”, ”TGA”}if stop_codon in stop_codons:    print(”Stop codon”)

1.3 in 与 not in 在条件判断中的使用

检查 motif:

seq = ”ATGCGTACGT”if ”CGT” in seq:    print(”Motif found”)

检查 DNA 是否有 ambiguous base:

if ”N” in seq:    print(”Sequence contains N”)
if ”N” not in seq:    print(”No ambiguous base”)

2. for:逐个处理 sequence 中的元素

for 是这一课最重要的部分。

最简单的例子:

seq = ”ATGC”for base in seq:    print(base)

2.1 遍历 string 和 list

String:

seq = ”ATGC”for base in seq:    print(base)

List:

genes = [”TP53”, ”EGFR”, ”KRAS”]for gene in genes:    print(gene)

再比如一批 reads:

reads = [    ”ATGCGT”,    ”GGCTAA”,    ”ATCCGT”]for read in reads:    print(read)

现在我们第一次可以真正表达:

对每一条 read 做某件事。

例如计算每条 read 的长度:

for read in reads:    print(len(read))
for read in reads:    gc_count = read.count(”C”) + read.count(”G”)    gc_content = gc_count / len(read)    print(f”{read}: {gc_content:.2%}”)

到这里,你已经开始写真正的批量 sequence-processing code 了。

2.2 用循环累积结果

例如,我们不用 .count(),自己统计 G 的数量:

seq = ”ATGCGGT”g_count = 0for base in seq:    if base == ”G”:        g_count = g_count + 1print(g_count)

你以后会大量看到这种模式:

count = 0for something in data:    if condition:        count += 1

其中:

count += 1

就是:

count = count + 1

的简写。

类似:

total += value

等价于:

total = total + value

2.3 用 dictionary 做碱基计数

现在可以把 Lesson 04 的 dictionary 加进来。

先建立:

counts = {    ”A”: 0,    ”C”: 0,    ”G”: 0,    ”T”: 0}seq = ”ATGCGGTAA”for base in seq:    counts[base] += 1print(counts)

3. 如何遍历 Dictionary

Dictionary 和 list 不太一样,因为它同时有key和value, 所以有几种不同的遍历方式。

3.1 直接遍历 dictionary:得到 key

sequences = {    ”seq1”: ”ATGCGT”,    ”seq2”: ”GGGAAA”,    ”seq3”: ”ATCCGT”}for seq_id in sequences:    print(seq_id)    print(sequences[seq_id])

3.2 .items():同时得到 key 和 value

items() 用来在循环中同时取得 dictionary 的 key 和 value。

这是以后最常用的 dictionary 遍历方式之一:

for seq_id, seq in sequences.items():    print(seq_id, seq)

你应该能看到上一课 tuple unpacking 的影子:

seq_id, seq = (”seq1”, ”ATGCGT”)

因为:

sequences.items()

本质上提供的是一组:

(key, value)
for seq_id, seq in sequences.items():    gc_count = seq.count(”G”) + seq.count(”C”)    gc_content = gc_count / len(seq)    print(f”{seq_id}: {gc_content:.2%}”)

这已经非常接近以后处理 FASTA的代码形式

sequence ID → sequence

3.3 遍历 set

bases = {”A”, ”C”, ”G”, ”T”}for base in bases:    print(base)

可以逐个取得四种 base。

但是不要写出这种逻辑:

“set 的第一个一定是 A,第二个一定是 C。”

因为 set 的目的本来就不是保存 position。

所以:

list → position 很重要set  → membership 更重要

4. range()、enumerate() 与 zip():需要位置时怎么循环?

普通:

for base in seq:

只能直接得到base

但 sequence algorithms 很多时候还需要:

当前位置 i

这时会用到这一组工具

4.1 range():生成整数序列

range() 用来产生一系列整数,最常用于按 index 循环。

for i in range(5):    print(i)

range() 可以指定起点和终点:

for i in range(2, 6):    print(i)

也可以加入 step:

for i in range(0,10,2):    print(i)

所以基本结构是:

range(start, stop, step)

类似于:

seq[start:stop:step]
seq = ”ATGC”for i in range(len(seq)):    print(i, seq[i])

4.2 enumerate():同时得到 index 和元素

刚才我们写:

for i in range(len(seq)):    print(i, seq[i])

Python 更常写成:

for i, base in enumerate(seq):    print(i, base)
for position, base in enumerate(seq, start = 1):    print(position, base)

这里有一个非常重要的生信应用。

Python index:

0-based

Rosalind 或某些 biological position:

1-based

于是:

enumerate(seq, start=1)

有时可以让输出位置更符合题目要求。

但要记住:

改的是循环产生的编号,不是 Python string 自己的 indexing 规则。

seq[0] 仍然永远是第一个字符。

4.3 zip():同时遍历多个对象

genes = [”TP53”, ”EGFR”, ”KRAS”]chroms = [”chr17”, ”chr7”, ”chr12”]for gene, chrom in zip(genes, chroms):    print(gene, chrom)

5. for 在序列算法中的真正用途

现在进入最重要的应用部分。

5.1 找所有 motif,而不是只找第一处

Lesson 02 我们学习了:

seq.find(motif)

它只能直接告诉我们第一处。

现在我们可以自己检查所有位置。

seq = ”GATATATGCATATACTT”motif = ”ATAT”for i in range(len(seq) - len(motif) + 1):    if seq[i:i+len(motif)] == motif:        print(i)

为什么是:

len(seq) - len(motif) + 1

假设:

sequence length = 10motif length    = 3

合法的起始 index 是:

0 1 2 3 4 5 6 7

总共:

10 - 3 + 1 = 8

个位置。

因此:

range(8)

恰好生成:

0 ... 7

如果继续到:

i = 8

剩下的 sequence 已经不够一个完整的 3-mer。

这条公式以后会不断回来:

长度为 n 的 sequence长度为 k 的 window共有:n - k + 1个完整 window

如果题目要求 1-based position:

for i in range(len(seq) - len(motif) + 1):    if seq[i:i+len(motif)] == motif:        print(i + 1)

5.2 生成所有 k-mer

现在 genome assembly 的一个核心操作已经可以正式写出来。

seq = ”ATGCGT”k = 3for i in range(len(seq) - k +1):    kmer = seq[i:i+k]    print(kmer)

如果不只是打印,而是希望以后继续使用,可以先建立空 list:

kmers = []for i in range(len(seq) - k + 1):    kmer = seq[i:i+k]    kmers.append(kmer)print(kmers)

所以非常经典的模式是:

results = []for item in data:    result = ...    results.append(result)

6. while 与循环控制

for 的含义通常是:

对这一批东西逐个处理。

while 的思维不同。

count = 0while count < 5:    print(count)    count += 1

为什么 while 要特别小心?

如果我们忘记count += 1

那么count永远是0,条件一直为true,于是形成infinite loop,也就是死循环。

所以写 while 时必须问自己:

什么东西最终会让这个条件变成 False?

这是一条非常好的检查原则。

break 与 continue

这两个属于“改变循环正常执行流程”,所以放在一起理解。

break:立刻结束整个循环

例如找到第一个 N 就停止:

seq = ”ATGCNTA”for base in seq:    if base == ”N”:        print(”N found”)        break

一旦碰到N

后面的字符不再继续检查。

适合:

找到第一个满足条件的对象后就已经完成任务。

continue:跳过当前这一轮

seq = ”ATGCNTA”for base in seq:    if base==”N”:        continue    print(base)

所以:

break→ 整个循环停止continue→ 只跳过当前这一轮

7. 一个综合例子:DNA sequence QC

给定:

sequences = {    ”seq1”: ”ATGCGT”,    ”seq2”: ”ATGCNT”,    ”seq3”: ”GGCCAA”,    ”seq4”: ””}

我们想检查:

空 sequence含 N正常 sequence

可以写:

for seq_id, seq in sequences.items():    if len(seq) == 0:        print(f”{seq_id}: empty seuence”)    elif ”N” in seq:        print(f”{seq_id}: contains N”)    else:        print(f”{seq_id}: valid”)

8. 本课练习

这次重点不是写很多题,而是把 if + for + 数据结构真正连起来。

Exercise A|检查 DNA sequence

给定:

seq = "ATGCNTAG"

逐个检查每个 base。

如果发现:

A / C / G / T

以外的字符,打印:

Invalid base: N

提示:

valid_bases = {"A", "C", "G", "T"}

思考如何组合:

for if not in

seq = ”ATGCNTAG”valid_bases = {”A”, ”T”, ”G”, ”C”}for base in seq:    if base not in valid_bases:        print(”Invalid base:”, base)        print(”Vaild bases = ”, valid_bases)

Exercise B|自己实现 nucleotide counting

不要使用:

seq.count()

给定:

seq = "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCT"

先建立:

counts = {     "A": 0,     "C": 0,     "G": 0,     "T": 0 }

然后只用:

for dictionary

完成计数。

最后输出:

A C G T

的数量。

这题非常重要。

seq = ”AGCTTTTCATTCTGACTGCAACGGGCAATATGTCT”counts = {    ”A” : 0,    ”T” : 0,    ”C” : 0,    ”G” : 0}for base in seq:    if base in counts:        counts[base] += 1print(counts)

Exercise C|所有 motif positions

给定:

seq = "GATATATGCATATACTT" motif = "ATAT"

找出 所有 motif 出现的位置。

要求输出:

1-based positions

seq = ”GATATATGCATATACTT”motif = ”ATAT”for i in range(len(seq) - len(motif) + 1):    if seq[i:i + len(motif)] == motif:        print(i+1)

Exercise D|生成 k-mer

给定:

seq = "ATGCGTAC" k = 4

生成所有 4-mer,并保存进:

kmers = []

seq = ”ATGCGTAC”k = 4kmers = []for i in range(len(seq) - k + 1):    kmer = seq[i:i+k]    print(kmer)    kmers.append(kmer)

Exercise E|小型 genomics QC

给定:

reads = [    ”ATGCGT”,    ”NNNNNN”,    ”ATGC”,    ””,    ”GGCCAATT”]

依次处理每条 read:

· 如果是空字符串,打印 "empty"

· 如果含 N,打印 "contains N"

· 否则,如果长度小于 5,打印 "too short"

· 其他情况打印 "pass"

reads = [    ”ATGCGT”,    ”NNNNNN”,    ”ATGC”,    ””,    ”GGCCAATT”]for read in reads:    if read == ””:        print(”empty”)    elif ”N” in read:        print(”contains N”)    elif len(read) < 5:        print(”too short”)    else:        print(”pass”)

最新文章

随机文章