<jupyter_start><jupyter_text>6-1. **内包表記**内包表記について説明します。参考:- https://docs.python.org/ja/3/tutorial/datastructures.htmllist-comprehensions- https://docs.python.org/ja/3/tutorial/datastructures.htmlnested-list-comprehensions リスト内包表記Pythonでは各種の**内包表記** (comprehension) が利用できます。以下のような整数の自乗を要素に持つリストを作るプログラムでは、<jupyter_code>squares1 = []
for x in range(6):
    squares1.append(x**2)
squares1<jupyter_output><empty_output><jupyter_text>`squares1` として `[0, 1, 4, 9, 16, 25]` が得られます。これを内包表記を用いて書き換えると、以下のように一行で書け、プログラムが読みやすくなります。<jupyter_code>squares2 = [x**2 for x in range(6)]
squares2<jupyter_output><empty_output><jupyter_text>関数 **`sum`** は与えられた数のリストの総和を求めます。（2-2の練習にあった `sum_list` と同じ機能を持つ組み込みの関数です。）内包表記に対して `sum` を適用すると以下のようになります。<jupyter_code>sum([x**2 for x in range(6)])<jupyter_output><empty_output><jupyter_text>以下の内包表記は3-2で用いられていました。<jupyter_code>[chr(i + ord('a')) for i in range(26)]<jupyter_output><empty_output><jupyter_text>練習文字列のリストが変数 `strings` に与えられたとき、それぞれの文字列の長さからなるリストを返す内包表記を記述してください。`strings = ['The', 'quick', 'brown']` のとき、結果は `[3, 5, 5]` となります。<jupyter_code>strings = ['The', 'quick', 'brown']
[ここに内包表記を書く]<jupyter_output><empty_output><jupyter_text>練習コンマで区切られた10進数からなる文字列が変数 `str1` に与えられたとき、それぞれの10進数を数に変換して得られるリストを返す内包表記を記述してください。`str1 = '123,45,-3'` のとき、結果は `[123, 45, -3]` となります。なお、コンマで区切られた10進数からなる文字列を、10進数の文字列のリストに変換するには、メソッド `split` を用いることができます。また、10進数の文字列を数に変換するには、**`int`** を関数として用いることができます。<jupyter_code>str1 = '123,45,-3'
[ここに内包表記を書く]<jupyter_output><empty_output><jupyter_text>練習数のリストが与えらえたとき、リストの要素の分散を求める関数 `var` を内容表記と関数 `sum` を用いて定義してください。以下のセルの `...` のところを書き換えて `var` を作成してください。<jupyter_code>def var(lst):
    ...<jupyter_output><empty_output><jupyter_text>上のセルで解答を作成した後、以下のセルを実行し、実行結果が `True` になることを確認してください。<jupyter_code>print(var([3,4,1,2]) == 1.25)<jupyter_output><empty_output><jupyter_text>内包表記の入れ子また内包表記を**入れ子**（**ネスト**）にすることも可能です:<jupyter_code>[[x*y for y in range(x+1)] for x in range(4)]<jupyter_output><empty_output><jupyter_text>ネストした内包表記は、外側から読むとわかりやすいです。`x` を `0` から `3` まで動かしてリストが作られます。そのリストの要素一つ一つは内包表記によるリストになっていて、それぞれのリストは `y` を 0 から `x` まで動かして得られます。以下のリストは、上の2重のリストをフラットにしたものです。この内包表記では、`for` が2重になっていますが、自然に左から読んでください。`x` を `0` から `3` まで動かし、そのそれぞれに対して `y` を `0` から `x` まで動かします。その各ステップで得られた `x*y` の値をリストにします。<jupyter_code>[x*y for x in range(4) for y in range(x+1)]<jupyter_output><empty_output><jupyter_text>以下の関数は、与えられた文字列のすべての空でない部分文字列からなるリストを返します。<jupyter_code>def allsubstrings(s):
    return [s[i:j] for i in range(len(s)) for j in range(i+1,len(s)+1)]

allsubstrings('abc')<jupyter_output><empty_output><jupyter_text>練習次のような関数 `sum_lists` を作成してください。- `sum_lists` はリスト `list1` を引数とします。- `list1` の各要素はリストであり、そのリストの要素は数です。- `sum_lists` は、`list1` の各要素であるリストの総和を求め、それらの総和を足し合せて返します。ここでは、内包表記と関数 `sum` を用いて `sum_lists` を定義してください。以下のセルの `...` のところを書き換えて `sum_lists` を作成してください。<jupyter_code>def sum_lists(list1):
    ...<jupyter_output><empty_output><jupyter_text>上のセルで解答を作成した後、以下のセルを実行し、実行結果が `True` になることを確認してください。<jupyter_code>print(sum_lists([[20, 5], [6, 16, 14, 5], [16, 8, 16, 17, 14], [1], [5, 3, 5, 7]]) == 158)<jupyter_output><empty_output><jupyter_text>練習リスト `list1` と `list2` が引数として与えられたとき、次のようなリスト `list3` を返す関数 `sum_matrix` を作成してください。- `list1`, `list2`, `list3` は、3つの要素を持ちます。- 各要素は大きさ 3 のリストになっており、そのリストの要素は全て数です。- `list3[i][j]` （ただし、`i` と `j` は共に、0 以上 2 以下の整数）は `list1[i][j]` と `list2[i][j]` の値の和になっています。ここでは、内包表記を用いて`sum_matrix` を定義してください。以下のセルの `...` のところを書き換えて `sum_matrix` を作成してください。<jupyter_code>def sum_matrix(list1, list2):
    ...<jupyter_output><empty_output><jupyter_text>上のセルで解答を作成した後、以下のセルを実行し、実行結果が `True` になることを確認してください。<jupyter_code>print(sum_matrix([[1,5,3],[4,5,6],[7,8,9]], [[1,4,7],[2,5,8],[3,6,9]])==[[2, 9, 10], [6, 10, 14], [10, 14, 18]])<jupyter_output><empty_output><jupyter_text>▲**条件付き内包表記**内包表記は`for`に加えて`if`を使うこともできます:<jupyter_code>words = ['cat', 'dog"', 'elephant', None, 'giraffe']
length = [len(w) for w in words if w != None]
print(length)<jupyter_output><empty_output><jupyter_text>この場合、`length` として要素が `None` の場合を除いた`[3, 3, 8, 7]` が得られます。  ▲**セット内包表記**内包表記はセット（集合）に対しても使うことができます:<jupyter_code>words = ['cat', 'dog"', 'elephant', 'giraffe']
length_set = {len(w) for w in words}
print(length_set)<jupyter_output><empty_output><jupyter_text>`length_set` として `{3, 7, 8}` が得られます。セット型なので、リストと異なり重複する要素は除かれます。  ▲**辞書内包表記**さらに、内包表記は辞書型でも使うことができます。<jupyter_code>words = ['cat', 'dog"', 'elephant', 'giraffe']
length_dic = {w:len(w) for w in words}
print(length_dic)<jupyter_output><empty_output><jupyter_text>`length_dic` として `{'cat': 3, 'dog': 3, 'elephant': 8, 'giraffe': 7}` が得られます。長さと文字列を逆にするとどうなるでしょうか。<jupyter_code>length_rdic = {len(w): w for w in words}
print(length_rdic)<jupyter_output><empty_output><jupyter_text>▲**ジェネレータ式**内包表記と似たものとして、ジェネレータ式というものがあります。リスト内包表記の `[]` を `()` に置き換えれば、ジェネレータ式になります。ジェネレータ式は、4-2で説明した**イテレータ**を構築します。4-2で説明したように、イテレータは、for文で走査（全要素を訪問）できます。<jupyter_code>it = (x * 3 for x in 'abc')
for x in it:
    print(x)<jupyter_output><empty_output><jupyter_text>イテレータを組み込み関数 `list()` や `tuple()` に渡すと、対応するリストやタプルが構築されます。なお、ジェネレータ式を直接引数とするときには、ジェネレータ式の外側の `()` は省略可能です。<jupyter_code>list(x ** 2 for x in range(5))
tuple(x ** 2 for x in range(5))<jupyter_output><empty_output><jupyter_text>総和を計算する組み込み関数 `sum()` など、リストやタプルを引数に取れる大抵の関数には、イテレータも渡せます。<jupyter_code>sum(x ** 2 for x in range(5))<jupyter_output><empty_output><jupyter_text>上の例において、ジェネレータ式の代わりにリスト内包表記を用いても同じ結果を得ますが、計算の途中で実際にリストを構築するので、メモリ消費が大きいです。ジェネレータ式では、リストのように走査できるイテレータを構築するだけなので、リスト内包表記よりメモリ効率が良いです。したがって、関数に渡すだけの一時オブジェクトには、リスト内包表記ではなくジェネレータ式を用いるのが有効です。  練習の解答<jupyter_code>strings = ['The', 'quick', 'brown']
[len(x) for x in strings]
str1 = '123,45,-3'
[int(x) for x in str1.split(',')]
def var(lst):
    n = len(lst)
    av = sum(lst)/n
    return sum([(x - av)*(x - av) for x in lst])/n
def var(lst):
    n = len(lst)
    av = sum(lst)/n
    return sum([x*x for x in lst])/n - av*av
def sum_lists(list1):
    return sum([sum(lst) for lst in list1])
def sum_matrix(list1,list2):
    return [[list1[i][j] + list2[i][j] for j in range(3)] for i in range(3)]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17474930133157981, 'fraction_numerical': 0.03304290646062798, 'mean_word_length': 10.041742286751361, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 93, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '23', 'dir': 'jupyter-structured-clean-dedup', 'id': '137199', 'license': 'MIT', 'n_tokens_mistral': 4077, 'n_tokens_neox': 3797, 'n_words': 385, 'path': '6/6-1.ipynb', 'repo_name': 'salikh/utpython', 'size': '6083'}