Pythonでwhile
ループまたはfor
ループを使用する必要がある場合に問題を見つけています。人々はfor
ループを使用することを好むようです(コード行が少ない?)。どちらを使用すべきか、特定の状況はありますか?個人的な好みの問題ですか?これまで読んだコードは、それらの間に大きな違いがあると思いました。
はい、whileとforには大きな違いがあります。
forステートメントは、コレクション、反復可能オブジェクト、またはジェネレーター関数を反復処理します。
whileステートメントは、条件がFalseになるまでループします。
好みではありません。それはあなたのデータ構造が何であるかという問題です。
多くの場合、処理する値をrange
(実際のリスト)またはxrange
(値を生成する)として表します。これにより、forステートメント用にカスタマイズされたデータ構造が得られます。
ただし、通常、既製のコレクションがあります。セット、タプル、リスト、マップ、または文字列さえも既に反復可能なコレクションなので、単純にforループを使用します。
いくつかのケースでは、いくつかの機能プログラミング処理を実行したい場合があります。その場合、反復の一部としてその変換を適用できます。 sorted
およびenumerate
関数は、forステートメントに自然に適合する反復可能オブジェクトに変換を適用します。
繰り返し処理するきちんとしたデータ構造がない場合、または処理を実行するジェネレーター関数がない場合は、whileを使用する必要があります。
while
は、ブレーク条件が論理的にどのようなシーケンスにも依存しないシナリオで役立ちます。たとえば、予測不可能な相互作用を考えます。
while user_is_sleeping():
wait()
もちろん、あなたはcouldそのアクションをカプセル化し、for
を介してアクセス可能にする適切なイテレータを記述しますが、それはどのように読みやすさを提供しますか?¹
Pythonの他のすべてのケースでは、for
(またはループをカプセル化する適切な高階関数)を使用します。
¹user_is_sleeping
関数は、falseのときにFalse
を返します。サンプルコードは、次のfor
ループとして書き換えることができます。
for _ in iter(user_is_sleeping, False):
wait()
for
は、リストを反復するためのよりPythonyの選択です。これは、より単純で読みやすいためです。
例えばこれは:
for i in range(11):
print i
これよりもはるかにシンプルで読みやすいです:
i = 0
while i <= 10:
print i
i = i + 1
まず、pythonと他の言語のforループには違いがあります。pythonの場合、値のリストを反復処理します(例:for value [4,3,2,7])では、他のほとんどの言語(C/C++、Java、PHPなど))ではwhileループとして機能しますが、読みやすくなっています。
一般的にforループは、反復回数(配列の長さなど)がわかっている場合に使用され、whileループは、それがどれくらいの時間かかるかわからない場合に使用されます(たとえば、 bubble sort =値がソートされていない限りループするアルゴリズム)
イテラブルの処理を検討してください。 for
ループでそれを行うことができます:
for i in mylist:
print i
または、while
ループを使用して実行できます。
it = mylist.__iter__()
while True:
try:
print it.next()
except StopIteration:
break
これらのコードブロックはどちらも、基本的に同じ方法で基本的に同じことを行います。ただし、for
ループはイテレータの作成とStopIteration
例外の処理を隠しているので、イテレータを自分で処理する必要はありません。
while
ループを使用して反復可能オブジェクトを処理すると考えることができるのは、何らかの理由でイテレータに直接アクセスする必要がある場合だけです。状況によってはリスト内のアイテムをスキップする必要がありました。
通常forループは、反復処理の内容を明確にします。常に直接使用できるわけではありませんが、ほとんどの場合、whileループを使用した反復ロジックはジェネレーター関数内にラップできます。例えば:
def path_to_root(node):
while node is not None:
yield node
node = node.parent
for parent in path_to_root(node):
...
の代わりに
parent = node
while parent is not None:
...
parent = parent.parent