Pythonで二重ループ(for文の入れ子)の内包表記
他人のコードを見ていると2重ループが内包表記で記述されていることがある。
リストの要素を頻度順に並び変えるプログラムを考えていて、また見かけたのでこれを機に使い方を勉強した。
題材となるプログラムは、入力に対して以下のように出力がほしい。
入力:['c', 'c', 'b', 'd', 'c', 'b', 'a', 'b', 'e'] 出力:['c', 'c', 'c', 'b', 'b', 'b', 'd', 'a', 'e']
プログラムはこんな感じになるかと。
Case1は自分で考えたもの。難産だった。
Case2は他人さまのコードを参考に、for文の入れ子で記述したもの。
Case3はCase2を内包表記で書いたもの。
from collections import Counter as cont def case1(dataset): s_dataset = cont(dataset).most_common() result = [] for i in range(len(s_dataset)): for j in range(s_dataset[i][1]): result.append(s_dataset[i][0]) return result def case2(dataset): result = [] for k, v in cont(dataset).most_common(): for i in [k] * v: # ['a'] * 3 = ['a', 'a', 'a'] result.append(i) return result def case3(dataset): # showing case2 in a way of list comprehensitions return [i for k, v in cont(dataset).most_common() for i in [k] * v] if __name__ == "__main__": dataset = ['c', 'c', 'b', 'd', 'c', 'b', 'a', 'b', 'e'] print("case1_result ->", case1(dataset)) print("case2_result ->", case2(dataset)) print("case3_result ->", case3(dataset))
実行結果は以下の通り。
case1_result -> ['c', 'c', 'c', 'b', 'b', 'b', 'd', 'a', 'e'] case2_result -> ['c', 'c', 'c', 'b', 'b', 'b', 'd', 'a', 'e'] case3_result -> ['c', 'c', 'c', 'b', 'b', 'b', 'd', 'a', 'e']