1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python における内包表記

Posted at

Pythonでの内包表記について学習したのでここに記録として残す。

Pythonの内包表記とは、簡潔にリストや辞書を作成することができる機能でコード文が短くメモリ処理を少なくすることができるかつ、可読性も高めることができる。

内包表記の種類

内包表記には、

リスト内包表記、辞書内包表記、集合内包表記、ジェネレータ式がある

リスト内包表記

qiita.py
t = (1,2,3,4,5)

#通常処理
r = []
for i in t:   
    if i % 2 == 0:
        r.append(i)

print(r)
#内包表記

r = [i for i  in t if i % 2 == 0]   
print(r)

上記コードのように空のリストを作成して、タプルのt,t2をリストの中に格納して,偶数のみをリストに核の黄酒流処理を書くときに、for文でも処理を行えるが(#通常処理)、内包表記を行うと一文で書くことができる。
基本構文としては以下のようになる。

qiita.py

[ for 変数 in イテラブル if 条件]

処理としては、r=[]に二つ目のiにfor文でtを順番に代入していき、そのiを2で割ったものの余りが0の時に一つ目のiに代入され、rのリストが完成する。

また、ネストした内包表記も行うことができる。

.py

t = (1,2,3,4,5)
t2 = (5,6,7,8,9,10)



for i in t:  #通常処理
    for j in t2:
        r.append(i*j)

print(r)

r = [ i * j  for i in t for j in t2 ]#内包表記

print(r)

この内包表この処理の場合、rの中のforから処理を行い、iにt,jにはt2をそれぞれ代入していく最終的にfor文手前の掛け算が行われ、出力としては、通常処理と同じものになる。

.出力
[5, 6, 7, 8, 9, 10, 10, 12, 14, 16, 18, 20, 15, 18, 21, 24, 27, 30, 20, 24, 28, 32, 36, 40, 25, 30, 35, 40, 45, 50]

辞書内包表記

.dict
w = ["mon","tue","wed"]
f = ["coffee","milk","water"]

d = {}
for x , y in zip(w,f):
    d[x] = y
print(d)

d= {x:y for x,y in zip(w,f)}
print(d)

空のリストdを作り、for文で繰り返し処理を行う場合、zip関数を用いて、変数wとfのペアをタプルで作る。その後forループでペアを一つずつ取り出し、xとyにそれぞれ代入していく、dの中のxをキー、yを値として、dの辞書をプリントする。

内包表記では、キーと値のセットを作らなくても、x:yで認識され、for文で繰り返し処理を行いxとyにそれぞれw、fが代入され、キーと値の処理がされて出力される。

出力.
{'mon': 'coffee', 'tue': 'milk', 'wed': 'water'}

集合内包表記

set.
s = set()

for i in range(10): #通常処理
   if i % 2 == 0:
       s.add(i)
print(s)
s={i for i in range(10) if i % 2 ==0} #内包表記
print(s)

set()とは重複のないデータを管理するデータ型である。
リストやタプルとは違い、同じデータを格納はできない。

add()は新しい要素を追加する関数でsetと組み合わせてよく使われる。
すでに存在する要素を追加してもその要素は無視される。

この処理は、forループで0から9までの数字をiに代入していき、偶数のみをadd()を使いs代入していく。
内包表記では、addを使わずに、sをset()と定義しているため、forループを描くことで、重複するデータを排除し、出力される。
最初に定義した、変数iを飛び越えて、for文から先に処理を行い、最終的な処理結果を、一番はじめの変数に要素が格納され、出力される。

出力.
{0, 2, 4, 6, 8}

ジェネレーター内包表記

ジェネレーターとは、() を使ってジェネレーターオブジェクトを作成し、必要なときに1つずつ値を取り出せるのが特徴。リストやタプルと違い、要素全ての処理をせずnextやyieldで一つずつ処理をされるので、メモリ効率が良い。
試しにジェネレーターを書いてみる。

def g():
    for i in range(10):
        yield i
g=g()
print(next(g))
出力.
0

iに9までの数字を格納したのちにyieldで一つずつ要素を取り出している処理を行い、変数gに格納する。
それをprintで呼び出し、nextで出力すると、一番はじめの要素0が取り出され出力される。

これを内包表記でやってみる。

g= (i for i in range(10)if i % 2 == 0)
print(type(g))
print(next(g))

for x in g :
    print(x)

タプルと間違えやすいためtypeを出力してある。
また、forループで全ての要素を最後に取り出しているため、後にnextで呼び出してもエラーになるため注意。

出力
<class 'generator'>
0
2
4
6
8

基本的に他の内包処理と書き方は同じだが、一度取り出した要素は使えないため、for文の後に要素を取り出そうとしても、取り出せない。

通常通りジェネレーターを書くときと違って、yieldを使い関数を定義しなくてもいい。

処理としては、forループで9までの数字をiに格納し偶数のみをiにTrueとして格納する。

print(next)で出力し0を出力。
その後、forループを使うと自動でnext()を呼び出しプログラムが終了する。

※タプルとして呼び出したい時はg=の後にtupleと宣言する

まとめ

リスト内包表記 [式 for 変数 in イテラブル if 条件] list
辞書内包表記 {キー: 値 for 変数 in イテラブル if 条件} dict
セット内包表記 {式 for 変数 in イテラブル if 条件} set
ジェネレータ式 (式 for 変数 in イテラブル if 条件) generator

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?