Python.use(better)《余録》comprehension: list
comprehension: list
《著》小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2001/03/02 ● 第1版♪2003/05/25 ● 第2版♪2004/06/01 ● 第3版♪2009/02/28
さまざまな事例
簡単な事例を使って、comprehension の理解を深めます。
《Note》Smalltalk-80 セミナーのために用意した課題です。ここでは「コレクションを扱う基本的なプロトコル(collect:/select:/reject:/detect:/inject:into:)を利用する」という制約を課してあるので、問題解決の「最適解」を示すものではありません。
課題:九九の表
掛算の九九の表を作成する課題 *1 によって、comprehension に関する理解を深めます。
■ filter 版
組み込み関数 filter を利用した事例の後に、comprehension 版と比較します。
def multiplicationTable(): # step 0
for n in range(2, 10):
for e in filter(lambda e: not e%n, range(n, n*10)):
print("%2d"%e, end=" ")
print()
>>> multiplicationTable()
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
■ comprehension 版
comprehension を利用して、filter 版と同等の機能を実現します。
def multiplicationTable(): # step 1 for n in range(2, 10): for e in [e for e in range(n, n*10) if not e%n]: print("%2d"%e, end=" ") print()
まず、filter と同等の機能を、comprehension で実現します。
def multiplicationTable(): # step 2 for n in range(2, 10): s = ["%2d"%e for e in [e for e in range(n, n*10) if not e%n]] print(" ".join(s))
次に、各項目を形成するための手段を、comprehension で実現します。
def multiplicationTable(): # step 3 s = [" ".join( ["%2d"%e for e in [e for e in range(n, n*10) if not e%n]]) for n in range(2, 10)] print("\n".join(s))
そして、各行を形成するための手段を、comprehension で実現します。
def multiplicationTable(): # step 4 return "\n".join( [" ".join( ["%2d"%e for e in [e for e in range(n, n*10) if not e%n]]) for n in range(2, 10)])
最後に、関数の本体から、関数 print を排除します。
>>> print(multiplicationTable())
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
結果を出力するには、関数 print の引数に、関数呼び出し multiplicationTable() を指定します。
■ 局所関数版
局所関数を定義して、機能分割を行います。
def multiplicationTable3(): # step 5 def term(n): return [e for e in range(n, n*10) if not e%n] def line(n): return ["%2d"%e for e in term(n)] def table(): return [" ".join(line(n)) for n in range(2, 10)] return "\n".join(table())
- 局所関数 term では、各項目を形成するための手段を提供します。
- 局所関数 line では、各項目を生成するとともに、各行(段)を形成するための手段を提供します。
- 局所関数 table では、各行を生成するとともに、表を形成するための手段を提供します。
《付録》九九の表を作るだけなら
この課題では、filter/comprehension の理解を深めるために、制約を設けました。九九の表を作るだけの目的なら、次のようにするとよいでしょう。
def multiplicationTable(): # for/in for n in range(2, 10): for e in range(n, n*10, n): print("%2d"%e, end=" ") print()
def multiplicationTable(): # comprehension return "\n".join( [" ".join(["%2d"%e for e in range(n, n*10, n)]) for n in range(2, 10)])
def multiplicationTable(): # 局所関数 def line(n): return ["%2d"%e for e in range(n, n*10, n)] def table(): return [" ".join(line(n)) for n in range(2, 10)] return "\n".join(table())
》こちらに移動中です《
↑TOP