LoginSignup
2
5

More than 3 years have passed since last update.

Python 内包表記

Last updated at Posted at 2020-01-06

初めに

語彙力がないので注意してください。

内包表記とはなんぞや?

内包表記を使えば少ない行数でリストを定義することができる。
例えば0から99までの要素を追加するとき

No1(内包表記でない).py
intlist1=list()
for i in range(100):
    intlist1.append(i)

と3行もかかってしまうのに対して内包表記では

No1(内包表記).py
intlist=[n for n in range(100)]

と僅か1行でかけてしまう。
どうだ、興味が出てきただろう?

基本の構文

さて、まずは基本の構文を。
[最後に追加する要素 for counter in iterable]
と書く。さっきの0から99までの値がある要素のリストを解説すると

解説.py
intlist=[i for i in range(100)]
#[0,1,2,3,4,5,...97,98,99]

iの値に0~99が入り、最後に追加する要素のiを追加している感じ。
ん、なに?じゃあなぜ最後に追加する要素とcounterを分けて書いたかって?それは後でわかる。

if(後置)

さあ、それでは偶数のみを持つリストを作ってみる。(range(0,99,2)なんてものはない)

No2(内包表記でない).py
even=list()
for i in range(100):
    if i%2==0:
        even.append(i)

となり、読みやすく長い平凡なコードが出来上がった。しかしこれではつまらない。内包表記を使うと

No2(内包表記).py
even=[i for i in range(100) if i%2==0]
#[0, 2, 4, 6,...96,98]

となり、かっこいいコードが出来上がった。(読みにくい?んなもん知らん)
しかし、これでは初見の人では何の数字かが分かりにくい(わからないとは言ってない)
このコードで最後に追加する要素とcounterを分けた理由がわかるはず
(理由は察してください、俺にはそんな語彙力はない)

No2(初見対応)
even=[str(i)+'は偶数' for i in range(100) if i%2==0]
#>>['0は偶数', '2は偶数', '4は偶数',...'98は偶数']

と初見でもわかりやすくなった。

if,elseを含むやつ(条件演算子)

条件演算子についてはこれを参照されたし。
例えば偶数か奇数か参照するプログラムは

No3(内包表記でない).py
number=[]
for i in range(100):
    if i%2==0:
        number.append(str(i)+'は偶数')
    else:
        number.append(str(i)+'は奇数')

となる。こんな長いコードは誰が読みたくなるだろうか。内包表記では

No3(内包表記).py
number=[str(i)+'は偶数' if i%2==0 else str(i)+'は奇数' for i in range(100) ]

と大変短いコードになった。
ん?こんなん見せられてもわからんって?解説してやるよ。

No3(インデント).py
number=[str(i)+'は偶数' if i%2==0 else str(i)+'は奇数' for i in range(100)]
#      ひとつ前のif文の結果             でなければ        それを入れる

語彙力()

追記
@konandoiruasa からコメント
なんとstr(i)+うんたらかんたらの部分をもっと省略していたのである

number=[str(i)+('は奇数' if i%2 else 'は偶数') for i in range(100) ]#で若干短くなり
number=[str(i)+['は奇数', 'は偶数'][i%2==0] for i in range(100) ]#も同じ程度。

というのである。確かに納得のいくコードだ。自分の知識の浅さを知った。

極める

ここまでは簡単なものばかりだったがここからはパイソンの「コードは読みやすいように書け」という決まりなんてなんのその。全て内包表記で表す。

fizzbuzz

fizzbuzz.py
fizzbuzz=[]
for i in range(1,100):
    if i%15==0:
        fizzbuzz.append('fizzbuzz')
    elif i%3==0:
        fizzbuzz.append('fizz')
    elif i%5==0:
        fizzbuzz.append('buzz')
    else:
        fizzbuzz.append(i)

内包表記

fizzbuzz2.py
fizzbuzz=['fizzbuzz' if i%15==0 else 'fizz' if i%3==0 else 'buzz' if i%5==0 else i for i in range(1,100)]
#[1, 2, 'fizz', 4, 'buzz', 'fizz',...'fizz', 97, 98, 'fizz']

二次元配列

二次元配列.py
e=[]
e_=[]
for n in range(3):
    e_=[]
    for i in range(10):
        e_.append(i)
    e.append(e_)

内包表記

二次元配列2.py
e=[[i for i in range(4)] for n in range(3)]
#[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]

先端のリストを追加する感じ
ついでに五次元も

五次元配列.py
_f=[[[[[z for z in range(3)] for y in range(4)] for x in range(5)] for i in range(4)] for n in range(2)]
#[[[[[0, 1, 2], [0, 1, 2],......[0, 1, 2], [0, 1, 2]]]]]

二重ループ

g1=[[0,1,2],[3,4],[5,6,7]]
g=[]
for g2 in g1:
    for g3 in g2:
        g.append(g3)
g1=[[0,1,2],[3,4],[5,6,7]]
_g=[g3 for g2 in g1 for g3 in g2]
#[0, 1, 2, 3, 4, 5, 6, 7]

応用

金額の総和をを消費税込みで表示するプログラム

print(['合計は'+str(int(sum([int(input('商品{}の金額:'.format((i+1)))) for i in range(int(input('購入する商品の個数を入力し、金額を消費税抜きで入力していってください。購入する商品数:')))])*1.1))+'円です。(消費税込み)'])
購入する商品の個数を入力し、金額を消費税抜きで入力していってください。購入する商品数:4
商品1の金額:200
商品2の金額:100
商品3の金額:140000
商品4の金額:65520
['合計は226402円です。(消費税込み)']

説明は割愛

2
5
4

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
2
5