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

python Python
python
スポンサーリンク

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

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

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

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

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

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

解説していきます。

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

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

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

 

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

 

項目11:イテレータを並列に処理するにはzipを使う

ソースはこちら

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

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

 

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

“複数のイテレータを並列処理する場合はPythonの組み込み関数であるzip関数を用いて記述する事で処理が明確になる。入力対象の要素数が異なる場合はitertoolsのzip_longest関数を用いる事で安全にループを回すことが可能”

と言う事です。

 

イテレータの生成

Pythonでは関係したオブジェクトのリストを多数扱う

場合があります。例えば、リスト内に保持されている

名前から、その長さを算出したい場合は以下のように

記述可能です。

※リスト内包表記を用いてリストを生成しています。

 

生成されたlettersというリストは当然namesと

同じ要素数となっています。

 

複数のイテレータを処理するには

前提知識なしに複数のイテレータを並列処理する

方法を考えてみましょう。

 

ここでは入力されたnamesリストから、最も長い

名前と、その時の文字数を算出する処理を考えて

みたいと思います。

記述がうるさいですね。なぜかというとforループの中に

添字iが二回登場しているからです。どっちの要素に対しての

処理だったか混乱しそうになります。

では、enumerateを併用すればもう少し綺麗にソースが

かけるのではないでしょうか。試してみましょう。

少しだけ見た目が綺麗になりました。添字iの登場回数が

一回だけになったからです。でも実はさらにスッキリと

記述できる方法があるんです。

 

zip関数の利用

ようやく登場しました。冒頭から申しておりましたzip関数の

登場です。zipはPythonのビルトイン関数です。ですのでモジュールの

import をしなくても使用可能です。

早速zipを使って処理を書き直してみましょう。

 

という事でめでたし、めでたしです。

zipを使えば綺麗にコーディングする事ができました。

 

が、

 

zipを用いる場合は注意しないといけない事があります。

それが入力対象の要素数を揃えるという事です。

例えば、namesを宣言し、lettersを作成した後に、

names.append(‘xxxxx’)を実行したとしましょう。

そうすれば

names: 要素数5

letters: 要素数4

となるため、要素数が異なります。

この状態でzipを用いて並列処理した場合はどうなるでしょうか。

以下にその挙動を示します。

さて困りました。ループが勝手に中断されるという

挙動が起きてしまいました。

 

こうならない為にも、Pythonにはitertoolsの中に

zip_longest関数というものがあります。

使い方はzipと同じで、複数のイテレータを渡して

あげるだけです。入力同士を比較して、より多い

要素数分だけループを回してくれるという優れものです。

→入力要素数が異なる可能性があるならば、zip_longest

を用いるべきです。

先ほどの例を書き直してみましょう。

以上がzipを用いる場合の注意点です。

 

結論

  • 組み込み関数zipが複数のイテレータを処理するのに便利
  • zipを使う事で処理を明確にすることができる。
  • 異なる長さの入力を用いると、挙動不審となるので注意
  • 異なる長さを入力してしまう不安がある場合、itertools.zip_longest関数を使う。

 

以上!

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

コメント

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