30.内包表記

内包表記はpython独特の書き方で
一定の処理を簡素に書くための手法となります。

内包表記の書き方

リスト:[counter for counter in iterator] 
辞書 :{key:value for key,value in iterator} 
セット:{counter for counter in iterator}

内包表記を使ってリストを作る

In [1]:
# 内包表記で変数にリスト型を格納する
lis1 = [i for i in range(10)]
print(lis1)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

内包表記を使わない場合は

In [2]:
lis2 = []
for i in range(10):
    lis2.append(i)
print(lis2)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

内包表記は複数行にわたる処理を1行にまとめる事ができる。

内包表記を使って辞書を作る

In [3]:
# 内包表記でキーをenumerate , 値をrangeの結果として辞書型を作成
num_dict = {k:v for k,v in enumerate(range(2,30,3))}
print(num_dict)
{0: 2, 1: 5, 2: 8, 3: 11, 4: 14, 5: 17, 6: 20, 7: 23, 8: 26, 9: 29}

keyとvalueに該当するものが有れば辞書型を作成可能。

内包表記はIF文を用いることもできます。

内包表記 + IF文

リスト:[value for counter in iterator if conditions]

辞書 :{key:value if conditions for key,value in iterator}

内包表記 + IF , else文

リスト:[value if conditions else value for counter in iterator]

辞書:{k1 if conditions else k2 : v1 if conditions else v2 for key:value in iterator}

In [4]:
# リスト内包表記 + IF文
num_list = [i for i in range(15) if i%2==0]
print(num_list)
[0, 2, 4, 6, 8, 10, 12, 14]
In [5]:
# リスト内包表記 + IF , else文
num_list = [i if i%2==0 else 0 for i in range(15) ]
print(num_list)
[0, 0, 2, 0, 4, 0, 6, 0, 8, 0, 10, 0, 12, 0, 14]
In [6]:
# 辞書内包表記 + IF文
num_dict = {k:v for k,v in enumerate(range(2,30,3)) if k%2==0}
print(num_dict)
{0: 2, 8: 26, 2: 8, 4: 14, 6: 20}
In [7]:
# 辞書内包表記 + IF , else文
num_dict = {k if k%2==0 else 0 : v if k%2==0 else 0  for k,v in enumerate(range(2,30,3)) }
print(num_dict)
{0: 0, 8: 26, 2: 8, 4: 14, 6: 20}

辞書型はenumerateを用いずにzip関数でリスト2つを用いても作る事ができる。

In [8]:
lis_a = [1,2,3,4,5]
lis_b = ['a','b','c','d','e']
d2 = {k:v for k,v in zip(lis_a,lis_b)}
print(d2)
{1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}

リスト内包表記から辞書を作成する事もできます。

In [9]:
# リスト内包表記から辞書化
num_dict = dict((str(i),i) if i%2==0 else (i,str(i)) for i in range(10))
print(num_dict)
{9: '9', 1: '1', 3: '3', '8': 8, 5: '5', '0': 0, '2': 2, '4': 4, '6': 6, 7: '7'}

for文は複数書くことができます。

In [10]:
# 2重の内包表記
print([i*j for i in range(1,5) for j in range(1,4) ])
[1, 2, 3, 2, 4, 6, 3, 6, 9, 4, 8, 12]

これを通常のfor文で書いて見ましょう。

In [11]:
a5 = []
for i in range(1,5):
    for j in range(1,4):
        a5.append(i * j)
print(a5)
[1, 2, 3, 2, 4, 6, 3, 6, 9, 4, 8, 12]

後に書いた方が内側のfor文に該当します。

このように複数行に渡るものも1行でスッキリ書くことができるのが
内包表記の良いところです。

まずは通常の処理を正しく書くことから始め、
それを簡略化できる部分があれば、内包表記に変えてゆく
といった風にすると、上手に覚えることができると思います。