Python中級者への道-Effective Python備忘録_02

python Python
python
スポンサーリンク

どうもです。バオウです。

<<<本ブログの目的>>>

Effective Pythonという良書があります。

Python入門を脱却して、そろそろ中級者

になりたいなーって人向けの書籍です。

この連載ではEffective Pythonの中身を

解説していきます。

ソースは全てGitHubに掲載していますので

ご自由に閲覧いただければと思います。

詳細は第0回をご覧ください。

 

それでは早速参りましょう。

 

項目9:大きな内包表記にはジェネレータ式を考える

ソースはこちら

ソース内に解説を書いてますので、ご覧ください。

内容をかいつまんで説明します。

 

項目9で筆者が言いたい事を端的に言いますと、

“データ量が増えると、リスト内包表記ではプログラムがクラッシュする恐れがある。データ量が大きい事が想定されるならば、ジェネレータ式を適用すると良いし、そうすべきだ。”

と言う事です。

 

リスト内包表記の危険性

リスト内包表記は非常に便利ですし、私も良く使用

します。しかし、入力対象が大きなデータ、例えば

ネットワークソケットのような終わりのないデータ

が入力されると、プログラムがクラッシュする可能性

があります。なぜかというと、リスト内包表記は一度

処理が実行されると、リスト内の要素を全てメモリ内に

格納するからです。

格納したデータに対して処理をするので、大サイズの

データがドンっと入力されるとどうなるかは自明です。

最悪、プログラムがクラッシュする事も想定ます。

 

ではどうすれば良いのか?

答えは一つです。ジェネレータ式を用います。

リスト内包表記は'[]’を用いたのに対し、

ジェネレータ式は'()’を用います。タプル内包表記

とは言いません。これがまたいやらしいですね。

他の内包表記はこちらを参照

pythonの内包表記を少し詳しく - Qiita
# pythonの内包表記について (

 

ジェネレータ式の使用例

例えば、入力データの各要素を10倍して出力する場合を考えます。

リスト内包表記なら、以下の通りです。

 

ではジェネレータ式ならどう記述するのでしょうか。

それは以下の通りです。

ジェネレータ式の返り値は’generator object’となっています。

nextに値を渡してあげると、要素が一つずつ取り出され

て表示される事がわかります。

 

リスト内包表記vsジェネレータ式(速度面)

入力データサイズが大きい場合の、

リスト内包表記ジェネレータ式の速度差を

評価してみたいと思います。

ぜひご自身の環境にソースをコピペして評価

してみてください。

 

配列を10倍してプリントするだけの単純な

プログラムを対象としました。

私の環境では、約4倍程度の差が生じている

事が確認できました。

 

プログラムがクラッシュするのを防ぐ以外にも

速度面もジェネレータ式を用いる方がお得だと

いう事が分かります。

 

まとめ

リスト内包表記とジェネレータ式について、

データサイズが大きい場合を対象とした比較を

実施しました。

 

結論

  • リスト内包表記は入力データが大きすぎるとプログラムをクラッシュさせかねない。
  • ジェネレータ式は出力を1つずつ生成するので、メモリの心配がいらない。
  • 入力データサイズが大きくなると、ジェネレータ式を適用する方が高速動作する。

 

以上!

Python
スポンサーリンク
バオウをフォローする
マイナーなマイナー(Minor&Minner)

コメント

タイトルとURLをコピーしました