なぜこれは無限ループを作成しないのですか?
a=5
for i in range(1,a):
print(i)
a=a+1
またはこれ
for i in range(1,4):
print(i)
i=i-1
またはこれ
for i in range(1,4):
print(i)
i=1
for
ループを使用して無限ループを作成する方法はありますか?そのためのwhile
ループがあることは知っていますが、興味がありました。
range
はクラス であり、たとえばrange(1, a)
は、そのクラスのobjectを作成します。このオブジェクトは1回だけ作成され、ループの反復ごとに再作成されるわけではありません。これが、最初の例で無限ループが発生しない理由です。
他の2つのループは、range
オブジェクトとは異なり、ループ変数i
が再作成される(またはむしろreinitialized)各反復。ループ内でi
に割り当てた値は、ループが繰り返されるときに上書きされます。
for
ループを考えてみましょう。
_for item in iterable:
print(item)
_
iterable
が変更されていない限り、item
内のすべてのiterable
を1回ループするという考え方です。例えば、
_for item in [3, 2, 1, 666]:
print(item)
_
_3 2 1 666
_を出力します。特に、range(1, 4)
は反復可能な_[1, 2, 3]
_を表す簡単な方法であることがわかります。したがって、
_for i in range(1, 4):
print(i)
_
_1 2 3
_を出力します。
_a=5
for i in range(1,a):
print(i)
a=a+1
_
この場合、ループの開始時にrange(1,a)
が評価されますonce。
_for i in range(1,4):
print(i)
i=i-1
_
この場合、ループの本体内でi
および_i=i-1
_ステートメントを実行する前に、print
がループごとに再評価されます。
_for i in range(1,4):
print(i)
i=1
_
例2と同様に、i
はループごとに再評価されます。
この場合、for
ループがループしているイテレータを更新することはできません。
for i in range(a):
のrange
は実際には関数であり、値aを取り、ループする値を含むオブジェクトを返します。そのオブジェクトを作成したら、入力変数を好きなだけ変更でき、そのオブジェクトは変更されません。
リストを生成するmy_range
という独自の同様の関数を作成した場合を想像してみてください(組み込みのrange
関数はrange
を生成します)。
def my_range(end):
my_list = []
for i in range(end):
my_list.append(i)
return my_list
ここで、次のように新しい関数を使用する場合:
a = 4
for i in my_range(a):
print(i)
a += 1
ループしているリストはすでに作成されており、再作成されていないため、a
を変更してループしているリストオブジェクトを更新できないことは明らかです。すべてのループ。
Pythonで無限ループを作ることはできますか?はい、ループしているオブジェクトに新しいエントリを追加するだけです。例:
my_list = [0]
for i in my_list:
print(i)
my_list.append(i+1)
ここで、ループしているオブジェクトを更新しています。
for
ループとrange(..)
オブジェクトfor i in range(..):
Python doesnotと書くと、これをfor(int i = 0; i < n; i++)
のように変換します(Cプログラミング言語ファミリー)。
さらに、範囲オブジェクトは、for
ループの前に1回作成されます。 range(..)
オブジェクトは、それを構築するためにどの変数が使用されたかを知りません。構築されると、範囲は固定になります。
range(..)
をiterableオブジェクトと見なし、反復ごとに、iterableが生成する次のアイテムを取得します。したがって、for
ループで変数を設定するかどうかに関係なく、次の反復ではnoの効果があります。
python-2.x では、range(..)
は特定のオブジェクトではなく、リストを作成するための呼び出しです。したがって、range(10)
(for
ループなし)を呼び出すと、[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
が得られます。
では、なぜ例が機能しないのでしょうか。
a=5
for i in range(1,a):
print(i)
a=a+1
ここでは、range(..)
を1回作成します。その後、range(..)
オブジェクトが変更されるため、作成元の変数が変更される可能性があります。したがって、a
をインクリメントしても、range
オブジェクトが大きくなるわけではありません。
for i in range(1,4):
print(i)
i=i-1
毎回for
ループは、反復可能オブジェクトのnext項目を取ります。したがって、最初にrange
ループから1
を収集した場合、次の反復では、2
を収集します。これは、i
の値が何であるかに関係ありません。
for i in range(1,4):
print(i)
i=1
まったく同じ理由で:for
はnoti
の以前の値を考慮しません。反復可能な次のアイテムのみをフェッチします(ここではrange(..)
が生成されます)。 range(..)
は修正されているため、次のアイテムをfor
ループにフィードするだけです。
したがって、要素を生成し続ける反復可能オブジェクトを構築する必要があります。これを行う方法はitertools.count
です:
from itertools import count
for i in count():
# ...
pass
または、値に関心がない場合は、repeat
も使用できます。
from itertools import repeat
for _ in repeat(None):
# ...
pass
範囲はリスト(Python2)またはrange
オブジェクトのいずれかであり、どちらも有限であるためです。その範囲は、ループが開始する前に1回作成されます。ループ変数は、ループ本体の後半で何を割り当てるかに関係なく、各反復の開始時に範囲の次の要素に割り当てられます。無限forループには、無限イテレータが必要です。 itertools.cycle
:
from itertools import cycle
for x in cycle(range(5)):
# endless
range
は、内部で使用するために指定されたパラメーターをコピーします。したがって、後でそれらを変更しても効果はありません。毎回内部値からのみ作成されるループ変数と同じです。
ただし、list
のような可変オブジェクトを使用して反復する場合は異なります。
a = [1,2,3]
for i in a:
a.append(i)
このループは確かに無限に実行されます。