内包表記
Python の内包表記(Comprehension) はforやwhile よりも高速に動作します。
code: リスト内包表記の書式
オブジェクトは__iter__メソッドを持つものであれば何でもかまいません。
詳しくは後ほど解説していますが、今の時点ではfor文に与えるオブジェクトと同じものと理解しておきましょう。forはオブジェクトから1つずつ要素を取り出しながら、要素が尽きるまで処理をします。
code: python
>> data = range(10)
>> for d in data:
... print(d)
...
0
1
2
3
4
5
6
7
8
9
>> data
range(0, 10)
>> print(type(data))
<class 'range'>
>> '__iter__' in dir(data)
True
>> data = list()
>> print(type(data))
<class 'list'>
>> '__iter__' in dir(data)
True
リスト内包表記の基本的な例
次のようなリストを初期化する処理を考えてみましょう。
code: 0212_init_list_simple.py
data = list()
for i in range(10):
data.append(i)
print(data)
これをリスト内包表記で記述すると次のようになります。
code: 0213_init_list_comprehension.py
print(data)
for で記述するよりスッキリ書けます。
また、リスト内包表記は、for での記述と比べて、次のオーバーヘッドがないので処理が速くなります。
ループのたびにリストオブジェクトの append()を参照する
append() を関数として実行する
if をともなうリスト内包表記の例
リスト内包表記で if 文を書くことができ、条件式が真のときにカウンタの処理が実行されます。
次のリストに偶数をセットする例をみてみましょう。
code: 0214_loop_with_if.py
# range(0,10,2) とすれば if はいらない。あくまで例示のため (^o^)
data = list()
for i in range(10):
if i % 2 == 0:
data.append(i)
print(data)
これをリスト内包表記に変えると次のようになります。
code: 0215_list_comprehension_with_if.py
print(data)
else をともなったリスト内包表記の例
リスト内包表記のif文でelseも記述できます。この場合、ifの位置が for より前になるので注意が必要です。
次のような奇数を文字として、偶数は数値でリストを初期化する例を見てましょう。
code: 0216_loop_with_if_else.py
data = list()
for i in range(10):
if i % 2 == 0:
data.append(i)
else:
data.append(str(i))
print(data)
これをリスト内包表記に変えると次のようになります。
code: 0217_list_comprehension_with_if_else.py
print(data)
辞書内包表記 とセット内包表記
内包表記はリストだけに適用するものではなくて、辞書型(dict) や集合型(set)に対しても使えます。
リスト内包表記で例としてとりあげた初期化処理を辞書に適用してみます。
code: 0218_dict_comprehension.py
data = { str(i):i for i in range(10) }
print(type(data))
print(data)
# Output: <class 'dict'>
# Output: {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
集合型(set)に対しても内包表記は使えます。辞書内包表記と同じように{} で囲みますが、セット内包表記ではコロン(:) が不要です。
code: 0219_set_comprehension.py
data = { i for i in range(10) }
print(type(data))
print(data)
# Output: <class 'set'>
# Output: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
問: セット内包表記で結果的に要素がなかった場合はどうなるでしょうか?
all() / any() と組み合わせた内包表記
組み込み関数 all() と any() は要素全体に対して次の評価をした結果を返します。
all(): すべての要素が真であれば Trueを返し、そうでなけらば’ False を返す
any(): いずれかの要素が真であれば Trueを返し、そうでなければ False を返す
code: 0220_any_all.py
print(any(x))
print(all(x))
print(any(x) and not all(x))
内包表記とany() や all()を組み合わせて使用すると、要素全体の条件判断の結果を調べるような処理がとても簡潔に書けます。
code: 0221_any_all_list_comprehension.py
print( all( n > 3 for n in data) ) # 全部が3より大きいとき True
print( any( n > 3 for n in data) ) # 少なくとも1つは3より大きいとき True