はじめに
ケモインフォマティクスで学ぶPythonの条件分岐に引き続き、リピドミクス(脂質の網羅解析)を題材として「反復処理」について解説していきます。
ケモインフォマティクスの実践例を中心に説明していきますので、基本を確認したいという人は以下の記事を読んでからこの記事を読んでみてください。
for文
for
は、あらかじめ決まった回数だけ反復処理を行うときに使えます。
for 変数 in イテラブル(リストなど):
として、改行して半角スペース4つ分インデントして処理内容を記述します。
carbon_numbers = [16, 18, 20, 22, 24]
for Cn in carbon_numbers:
print(Cn, 0, sep=':')
上の例では、carbon numbers
を脂肪酸の炭素原子数(鎖長)のリストとして、それぞれに対応する飽和脂肪酸の略号を作成しています。
range
イテラブルとしてrange
を使うこともできます。
range
は、指定した範囲の連続した整数のリストのようなイメージです。
Cn = 22
for Un in range(4, 7):
print(Cn, Un, sep=':')
for Un in range(7):
print(Cn, Un, sep=':')
上の例では、range(4, 7)
は4から6までの連続した整数(4, 5, 6)を示します。
また、range(7)
と書くと、0から6までの連続した整数(0, 1, 2, 3, 4, 5, 6)を指すことになります。
ここでは、脂肪酸の不飽和度(炭素鎖における二重結合数)を示す数値を生成しています。
enumerate
以下のように、enumerate
を使うことで、イテラブルのインデックス番号と要素をセットで取り出すことができます。
fatty_acids = ['FA 16:0', 'FA 18:0', 'FA 18:1']
for fatty_acid in fatty_acids:
print(fatty_acid)
for i, fatty_acid in enumerate(fatty_acids):
print(f'{i}: {fatty_acid}')
上の例では、i
にリストfatty_acids
のインデックス番号を、fatty_acid
にリストfatty_acids
の要素の値を順番に格納していき、print
で出力するという処理になっています。
辞書
辞書に対してもfor
を使った反復処理を行うことができます。
以下に例を示します。
fatty_acids = {'Palmitic acid': 'FA 16:0', 'Stearic acid': 'FA 18:0', 'Oleic acid': 'FA 18:1'} # 脂肪酸名(common name)と略号
for key in fatty_acids.keys(): # 辞書のキー
print(key)
for value in fatty_acids.values(): # 辞書の値
print(value)
for key, value in fatty_acids.items(): # 辞書のキーと値
print(f'{key} is {value}')
exact_mass = {'C': 12, 'H': 1.00783, 'O': 15.99491} # 元素記号と原子量
formula_pa = {'C': 16, 'H': 32, 'O': 2} # 元素記号と原子数(組成式)
em_pa = 0
for key, value in formula_pa.items():
em_pa += exact_mass[key] * value # 原子量と原子数を掛け算
print(em_pa)
fatty_acids = {16: [0, 1], 18: [0, 1, 2, 3, 4], 20: [0, 3, 4, 5], 22: [0, 4, 5, 6]} # 脂肪酸の炭素原子数をキーに、二重結合数を値とした辞書
for Cn, Uns in fatty_acids.items():
for Un in Uns:
print(Cn, Un, sep=':')
ここで、a = a + n
は、a += n
と書くことができます。em_pa += exact_mass[key] * value
の部分は、原子ごとに原子量と原子数を掛け合わせて、精密質量を計算する変数em_pa
に足し合わせるということを意味しています。
条件分岐との組み合わせ
もちろん、if
と組み合わせることもできます。
fatty_acids = ['FA 16:0', 'FA 18:0', 'FA 18:1', 'FA 18:2', 'FA 20:4', 'FA 22:6', 'FA 24:0']
saturated_fatty_acids = [] # 空のリスト(この後の処理で値を入れていく)
unsaturated_fatty_acids = [] # 空のリスト(この後の処理で値を入れていく)
for fatty_acid in fatty_acids:
if fatty_acid[-1] == '0':
saturated_fatty_acids.append(fatty_acid) # 飽和脂肪酸
else:
unsaturated_fatty_acids.append(fatty_acid) # 不飽和脂肪酸
print(saturated_fatty_acids)
print(unsaturated_fatty_acids)
breakとcontinue
以下のようにbreak
を使うと反復処理を中断します。
else
はbreak
されずに反復処理が終了した場合に行われる処理を記述するのに使います。
else
はなくても問題ありません。
fatty_acids = ['FA 16:0', 'FA 18:0', '', 'FA 18:1']
for fatty_acid in fatty_acids:
if fatty_acid == '':
print('空です。処理を中止します。')
break
print(fatty_acid) # 「FA 18:0」まで出力される
else:
print('処理が最後まで完了しました。') # ここでは出力されない
上の例では、リストfatty_acids
の左から3番目の要素が空となっているため、その前の要素まで反復処理が行われ、要素の値が出力されます。
今回の例では、break
により、処理が途中で中断されるためelse
以下は実行されません。
一方、continue
を使うと、反復処理がスキップされます。
fatty_acids = ['FA 16:0', 'FA 18:0', '', 'FA 18:1']
for fatty_acid in fatty_acids:
if fatty_acid == '':
print('空です。スキップします。')
continue
print(fatty_acid) # 空の要素は飛ばして「FA 18:1」まで出力される
上の例では、空白の要素はcontinue
によって処理がスキップされるため、要素の値が出力されることはありませんが、最後まで処理が行われ、「FA 18:1」も出力されます。
仮に、else
を入れた場合は、else
以下も実行されます。
応用:SMILES記法
ここで応用編として、SMILES記法で書かれた文字列から、炭素原子の数と、炭素鎖の二重結合の数を求めることを考えます。
smiles_fa = 'OC(CCCCCCC/C=C\C/C=C\CCCCC)=O'
Cn = 0
Un = 0
for i in range(len(smiles_fa)):
if smiles_fa[i] == 'C':
Cn += 1
elif smiles_fa[i] == '=' and smiles_fa[i+1] == 'C':
Un += 1
print(Cn, Un, sep=':')
左から文字列を見て行って、C
だった場合は炭素原子数を数える変数Cn
を1大きくし、=
で次の文字がC
だった場合(カルボニル炭素もあるため)に二重結合数を数える変数Un
を1大きくしています。
while文
while
を使うと、指定した条件が成立する限り、反復処理を行います。
while 条件:
として改行して半角スペース4つ分インデントして処理を記述します。
saturated_fatty_acids = ['FA 16:0', 'FA 18:0']
unsaturated_fatty_acids = ['FA 18:1', 'FA 18:2', 'FA 18:3', 'FA 20:4', 'FA 22:6']
fatty_acids = []
while len(saturated_fatty_acids) > 0:
fatty_acids.append(saturated_fatty_acids[-1])
saturated_fatty_acids.pop()
while len(unsatturated_fatty_acids) > 0:
fatty_acids.append(unsaturated_fatty_acids[-1])
unsaturated_fatty_acids.pop()
print(fatty_acids)
上の例では、元々あるリストsaturated_fatty_acids
とunsaturated_fatty_acids
の後ろから要素を取り出して新しい空のリストfatty_acids
に移し替えるという処理をしています。
ここで、len(リスト) > 0
はリストに何らかの要素が含まれている場合を指します。fatty_acids
に要素を移した後は、pop
で元のリストからは要素を削除するようにしています。この削除を忘れると、処理が無限回繰り返される(無限ループになる)ので注意が必要です。
応用:SMILES記法
最後に応用編として、SMILES記法でwhile
を使って炭素原子数を数えることを考えてみます。
smiles_fa = 'OC(CCCCCCCCCCCCCCC)=O'
Cn = 0
while 'C' in smiles_fa:
if smiles_fa[0] == 'C':
Cn += 1
smiles_fa = smiles_fa[1:]
print(Cn)
SMILESの文字列にC
という文字が含まれ、なおかつ一番左の文字がC
の場合は、炭素原子数を数える変数Cn
を1大きくします。
一番左の文字はC
であるかどうかに関わらず毎回消去します。
こうすることで、SMILESの中のC
の数を数えることができます。
以上のように、for
は繰り返し回数が決まっている場合に、while
は繰り返し回数が決まっていない場合に使うことになります。
まとめ
ここでは、Pythonの反復処理について、ケモインフォマティクスで使える実践的な知識を中心に解説しました。
もう一度要点をおさらいしておきましょう。
-
for
は、繰り返し回数が決まっているときに使える。break
やcontinue
で特定の条件のもとで処理を中止したり、スキップしたりすることもできる。 -
while
は、繰り返し回数が決まっておらず、あらかじめ設定した条件を満たすまで処理を繰り返すのに使える。「無限ループ」とならないように注意する必要がある。
続いて、Pythonの関数について以下の記事で解説しています。