次回より『ヒデログ』とご検索ください

【Python入門】for文の内包表記(if・if-else・enumerate・zip)の使い方

python

Pythonの内包表記は分かりにくいですが、これを使えると配列の作成コードがすっきりします。

今回はfor文内包表記で使われる、if文、if-else文、enumerate、zipを使ったすべてのパターンを紹介します。

ひでひろ
Pythonの内包表記は便利なので勉強しましょう。

for文の内包表記

Pythonでは、配列をシンプルなコードで作成できる内包表記という書き方があります。

内包表記を用いると本来であれば、複数行で書かなければならないコードを1行のコードで書けます。[ ]を使って一行で書かれているものが内包表記となります。

for文は長くなりますし、さらにif文が入ってくればさらに長いループ分になります。それを1行で書くことができれば、長くなるソースコードを短くすることができます

慣れるまでとっつきにくい表記ですが、慣れればむしろ読みやすいです。

1つ1つのパターンを内包表記を用いずに書いた時のと対比を示しながら、内包表記の様々なパターンを解説していきます。

公式マニュアル:»Python チュートリアル

シンプルなfor文の内包表記(range)

rsl=[a*2 for a in range(5)]
# [0, 2, 4, 6, 8]

単純for文で作ると

rsl=[]
for a in range(5):
    rsl.append(a*2)

3行で書けるものが1行で書けていることが分かります。

後者のfor文はどの言語でもよくあるfor文の書き方です。range(5)[0,1,2,3,4]の配列をコレクションとしてfor文を形成しています。

コード解説

range(5)で生成される[0,1,2,3,4]を2倍にした配列を返しています。

シンプルなfor文の内包表記(配列)

arr=[2,3,4,5,6]
rsl=[a*2 for a in arr]
# [4, 6, 8, 10, 12]

内包表記を使わないfor文

rsl=[]
arr=[2,3,4,5,6]
for a in arr:
    rsl.append(a*2)

コード解説

配列arrをコレクションとしてfor文を回して、その値を2倍しています。後者のfor文では、appendメソッドで1つ1つ逐次配列に要素を追加しています。それを前者では1行で書けるコードになっています。

zip関数を使ったfor文の内包表記

arr=[2,3,4,5,6]
brr=[7,8,9,10,11]

rsl=[a*b for a,b in zip(arr,brr)]
# [14, 24, 36, 50, 66]

zip自体はイテレータになります。

内包表記を使わない

arr=[2,3,4,5,6]
brr=[7,8,9,10,11]

rsl=[]
for a,b in zip(arr,brr):
    rsl.apend(a*b)

zip関数を使わないfor文

arr=[2,3,4,5,6]
brr=[7,8,9,10,11]

lp=min(len(arr),len(brr))

rsl=[]

for i in range(lp):
    rsl.append(arr[i]*brr[i])
rsl

コード解説

zip関数で配列の値最小の要素数を取得し、コレクションとします。

前者では最小の要素数をzip関数で取得し、コレクションを生成してますが、後者ではそれをmin関数で計算しなくてはならず、コードが長くなります。

enumerate関数を使ったfor文の内包表記

arr=[2,3,4,5,6]
# i:ループのi番目
# a:i番目のarrの要素
rsl=[a*2 for i,a in enumerate(arr)]
# [4, 6, 8, 10, 12]
arr=[2,3,4,5,6]
rsl=[i for i,a in enumerate(arr)]
# [0, 1, 2, 3, 4]

enumerate関数を使ったfor文の抽象化

for i,f(x) in enumerate(x)
i:xのi番目の要素

[for 要素番号, 式 in enumerate(配列)]

内包表記を使わない

arr=[2,3,4,5,6]
rsl=[]

# i:ループのi番目
# a:i番目のarrの要素
for i,a in enumerate(arr):
    rsl.append(a*2)

enumerateを使わないfor文

arr=[2,3,4,5,6]
rsl=[]
for i in range(len(arr)):
    rsl.append(arr[i]*2)

コード解説

enumeratearrのイテレーターになっていて、iに関しては0から始まるループ回数を表しています。

enumerateとzip関数を使った内包表記

arr=[2,3,4,5,6]
brr=[7,8,9,10,11]
rsl=[x for i,x in enumerate(zip(arr,brr))]
# [(2, 7), (3, 8), (4, 9), (5, 10), (6, 11)]

enumerateもzipも使わないfor文

arr=[2,3,4,5,6]
brr=[7,8,9,10,11]
lp=min(len(arr),len(brr))
rsl=[]
for i in range(lp):
    rsl.append((arr[i],brr[i]))

コード解説

arrbrrの短い配列分を取得し、arrbrrの要素の順番に2次元配列を作成しています。

for文にif文が入った内包表記

arr=[2,3,4,5,6]
rsl=[a*2 for a in arr if a>4]
# [10, 12]

[ for 要素 in 配列 if 条件]という順番になっています。

通常のfor-if文

arr=[2,3,4,5,6]
rsl=[]
for i in range(len(arr)):
    if arr[i]>4:
        rsl.append(arr[i]*2)

コード解説

arrの要素で4より大きい要素を取り出し2倍して、配列を作り直しています。

for文にif-else文が入った内包表記

arr=[2,3,4,5,6]
rsl=[(a*-2 if a>4 else a**2) for a in arr]
# [4, 9, 16, -10, -12]

[式1(if時) if 条件 else 式2(else時) for 要素 in 配列]という順番になっている。

if文の場合は、最後についているが、if-else文の時は先頭についている違いがあるので注意が必要。

  • if文:for表記の後に付ける
  • if-else文:for表記の前に付ける
[ for 要素 in 配列 if 条件]
[式1(if時) if 条件 else 式2(else時) for 要素 in 配列]

通常のfor-if-else文

arr=[2,3,4,5,6]
rsl=[]
for i in range(len(arr)):
    if arr[i]>4:
        rsl.append(arr[i]*-2)
    else:
        rsl.append(arr[i]**2)

コード解説

arr配列で4より大きい要素は-2倍し、4以下の要素は2乗して配列を作成しています。

まとめ

内包表記を使うとコードが短くなることが分かりました。慣れれば分かりやすいので、何度か写経をして覚えていくことをおすすめします。

ひでひろ
内包表記を使うとソースコードがすっきりするね

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です