1
1

More than 1 year has passed since last update.

whileをforで代用しよう

Posted at

はじめに

皆さんは,whileを使うべきコードをあえてforで書きたくなったことはありますか? (私はありません。)
今回は,そんな素直じゃない皆さんのためにwhileforで代用する方法を紹介します。

逆は簡単

今回やる逆の「forwhileで代用する」はかなり簡単に実現できます。
forが実際にどういう処理なのかを知っておくとwhileを実装する際に理解しやすくなりため一応紹介しておきます。

Pythonのforはひたすらイテレータをnextで叩いてStopIteration例外が飛んで来たら止めるだけです。
てなわけで

i = iter(range(10))
while True:
  try:
    item = next(i)
    print(item)
  except StopIteration:
    break

のようにすればOKです。

この辺りの事情を知りたい方はCpythonのソースでも眺めてみるといいかもしれません。

カスタムイテレータ

ループ回数がわからないwhileforで実現するのは難しそうなので,カスタムイテレータを定義します。
カスタムイテレータは__next____iter__を持つクラスで,この2つのメソッドがあることでforに食わせることができます。
__next__は上で紹介したnextのよって呼ばれるメソッドです。
この中で条件式を評価してあげればよいでしょう。
これを実装してあげると

class WhileIter():
  def __init__(self, cond):
    self.cond = cond
  
  def __next__(self):
    if self.cond():
      return None
    raise StopIteration
  
  def __iter__(self):
    return self

のようになります。

これを使う時は

n = 0
for _ in WhileIter(lambda: n < 10):
  print(n)
  n += 1

のようにします。
条件式condは引数を取らずboolとして評価可能な値を返す関数ですが,条件式ごときに関数を定義する必要もないので無名関数としています。

メリット・デメリット

この方法を採用することには,以下のようなメリットとデメリットがあります。

メリット

特になし。

デメリット

  • 可読性が悪い。何がしたいのかわからない。何か特別な意図があるのかと考えてしまう。
  • 条件評価→ジャンプだけのwhileに対して余計な処理が増えるのでパフォーマンスが低下する可能性がある。
  • 頭がおかしいのではないかと同僚に勘違いされる。

etc...

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1