情報学部大学生のダラダラ日記

β日記

機械学習や日記っぽいものを書きます

便利なPythonのリスト内包表記

スポンサーリンク

最近、競プロみたいな問題をPythonで解いたりしているのですが、その時にデータの入出力周りでリストをよく扱います。いたずらにfor文とappend()メソッドを用いるとコードが冗長になってしまうのでリスト内包表記を用いるのですがちゃんと調べたことがなかったので調べて備忘録としてまとめます。

 

リスト内包表記のメリット・デメリット

  • コードが短くなる
  • 実行速度が上がる
  • Pythonわかってる風になれる
  • あまりディープな表記にすると可読性が著しく下がる

シンプルなリスト内包表記

元データ

for文
data = 
for i in range(10):
    data.append(i)
print(data)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
リスト内包表記

[式 for 変数 in イテラブルオブジェクト]といった形です。上記のfor文記法と比較するとわかりやすいと思います。

data = [i for i in range(10)]
print(data)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
補足

上記の例ではrange()から1つずつ要素を抽出しましたが、そのままlist()関数でリスト化できます。

data = list(range(10))
print(data)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

リストの型を変える

先ほどのリストの各要素はint型です。それをstr型に変更します。

for文
data_str = 
for i in data:
    data_str.append(str(i))
print(data_str)
#['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
リスト内包表記
data_str = [str(i) for i in data]
print(data_str)
#['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
補足

map関数を使うことで同様の処理をすることができます。

data_str = list(map(str,data))
print(data_str)
#['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

 

if文のあるリスト内包表記

if文のみ

for文
data_if = 
for i in data:
    if i == 2 or i == 8:
        data_if.append(i)
print(data_if)
#[2, 8]
リスト内包表記

[式 for 変数 in イテラブルオブジェクト if文]といった形です。

data_if = [i for i in data if i == 2 or i == 8]
print(data_if)
#[2, 8]

if-else

まず、先ほど作成したdata_strに要素を追加します。

data_str.append('G')
print(data_str)
#['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'G']
for文

int型への変更が可能であるならばint型にし、不可能ならばそのままにするプログラムです。

data_ifelse = 
for i in data_str:
    if i.isdigit():
        data_ifelse.append(int(i))
    else:
        data_ifelse.append(i)
print(data_ifelse)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'G']
リスト内包表記

先ほどのif文と位置が異なります。

[Trueの式 if 式 else Falseの式 for 変数 in イテラブルオブジェクト]と書きます。

elif文はif-elseを組み合わせて記述することができますが、可読性が落ちてしまうので辞めた方がいいかもしれません。

data_ifelse = [int(i) if i.isdigit() else i for i in data_str]
print(data_ifelse)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'G']

 

まとめ

今回はPythonのリスト内包表記についてまとめました。内包表記はリストだけでなく、dict型やset型にも同様に使えるので試してみてください。繰り返しになりますが、ここで挙げた以上の複雑な処理を内包表記で書くととても読みにくくなってしまうので注意が必要です。実行速度が上がるとメリットで書きましたが、そこまで大きな差はなく、これぐらいを気にするのならばリストではなくnumpy配列等を使った方がよほど早くなります。

 

 

スポンサーリンク