Python の内包表記


こんにちは、切口太郎です。


Pythonには、内包表記という独特な記述方法があります。


内包表記とは、ブロックのプログラムを1行で記述する方法です。
「1行野郎」または、「ワンライナー」と呼ぶ人もいます。


内包表記を使うメリットはこの3つです。

① コーディング量が減ってソースが見やすくなる
② 実行速度がちょっとだけ早くなる。
③ 内包表記を書くとなんとなくプログラムが上手くなったように見える。
 

内包表記の例を見てみましょう!

リストの内包表記


リストへデータを登録するプログラムです。

lst = []
for value in range(10):
    lst.append(value)

これを内包表記で記述するとこうなります。

lst = [value for value in range(10)]

どういうルールで内包表記ができているか2つの書き方を対比してみます。

普通に書いた Python内包表記
lst = []
for value in range(10):     
    lst.append(value)                  
lst = [value for value in range(10)]
lst = [value for value in range(10)]
lst = [value for value in range(10)]

太字の部分が、対応している部分です。
1行の中に要素を詰め込んで書いている感じです。

このようなルールになっています。

変数名=[ <for文の変数名>  <for文>]

<> は、要素の囲みを表しています。<> の記述はありません。

簡単に言っちゃうと、for文の変数名 + for 文をリストの[] の中に記述します。


タプルは、要素の追加ができないので、内包表記で記述することができません。
lst.append(value) の append メソッドがタプルには無いためです。


リストに if 文を加えた内包表記


先程のリストへの内包表記に if文で条件を設定してデータを登録する方法です。
偶数の数字だけ、リストに登録するプログラムです。

lst = []
for value in range(10):
    if value % 2 == 0:
        lst.append(value)

太字の部分が、先程のリストへの登録プログラムに追加したコードです。


内包表記だとこうなります。

lst = [value for value in range(10) if value %2 == 0]

実行するとこのようにデータが設定されています。

>>> lst = [value for value in range(10) if value %2 == 0]
>>> print(lst)
[0, 2, 4, 6, 8]

このままだと、呪文みたいなので、普通のPythonプログラムと内包表記との対比をしてみます。

lst = []
for value in range(10)
    if value % 2 == 0
        lst.append(value
lst = [value for value in range(10) if value %2 == 0]
llst = [value for value in range(10) if value %2 == 0]
lst = [value for value in range(10) if value %2 == 0]
lst = [value for value in range(10) if value %2 == 0]

太字の部分が対応している部分です。

if文を追加した内包表記のルールはこうです。

変数名=[ <for文の変数名>  <for文> <if文>]

<> は、要素の囲みを表しています。<> の記述はありません。

簡単に言っちゃうと、for文の変数名 + for 文 + if文 をリストの[] の中に記述します。

ELSE句付きの if 文


今度は、else 句付きの if 文を、内包表記で記述する方法です。

else 句月の if文は 構文順序が変わってしまうので、わかりにくくなります。

サンプルは、奇数は -1 にしてリストへ格納するプログラムです。

lst = []
for value in range(10):
    if value % 2 == 0:
        lst.append(value)
    else:
        lst.append(-1)
太字の部分が、いままでのサンプルに else 句を追加したものです。

内包表現で記述するとこうなります。

lst = [value if value %2 == 0 else -1 for value in range(10) ]

実行すると奇数が -1 に設定されているのが確認できます。

>>> lst = [value if value %2 == 0 else -1 for value in range(10) ]
>>> print(lst)
[0, -1, 2, -1, 4, -1, 6, -1, 8, -1]

さあ、呪文を解読してみましょう。

lst=[]
for value in range(10):  
    if value % 2 == 0:       
        lst.append(value
    else:                              
        lst.append(-1)      
lst = [value if value %2 == 0 else -1 for value in range(10) ]
lst = [value if value %2 == 0 else -1 for value in range(10) ]
lst = [value if value %2 == 0 else -1 for value in range(10) ]
lst = [value if value %2 == 0 else -1 for value in range(10) ]
lst = [value if value %2 == 0 else -1 for value in range(10) ]
lst = [value if value %2 == 0 else -1 for value in range(10) ]

内包表記と普通のプログラミを左右で比較しまいした。
同じ行の太字の部分が対応しています。

まとめると、ルールはこうなっています。

変数名=[ <for文の変数名>  <if文> <else句> <for文> ]

<> は、要素の囲みを表しています。<> の記述はありません。

簡単に言っちゃうと、for文の変数名 + if文 + else 句 + for 文 をリストの[] の中に記述します。


前の if 文の構文と順序が違って解りにくいですね。

内包表記で if 文を書く場合には、注意が必要です。

else句なしlst = [value for value in range(10) if value %2 == 0]
else句ありlst = [value if value %2 == 0 else -1 for value in range(10) ]


あまり複雑な内包表記は、ソースが読みにくくなるので、単純なものに留めましょう。
昔は複雑な記法を使って腕を競い合っていた時代もあったようですが、そんな事より確実に動かす事を優先しましょう。
そちらの方が、実りが多いです!


コメント

このブログの人気の投稿

Hyper-V で Docker Desktop for Windows を使う(その2)

Python の命名規約 - ネーミングルール

VS Code で Hyper-V + Docker Desktop for Windows