2016-10-08 7 views
0

この場合、range()はどのようにコールを区別しますか?'range()'は内部的にどのように動作しますか?

例:

def ex(): 
    list = [1,2,3,4] 
    for val in range(len(list)): 
     print(val) 
     break 
    for val in range(len(list)): 
     print(val) 
     break 

出力 - 要するに

0 
0 

、私の質問は、なぜ出力歩留まりこの方法はないでしょうか?

0 
1 

「ループの最初の」における範囲の最初の呼び出し()の間に、コールが「範囲(LEN(リスト))」、 範囲の最初の呼び出しで()内'second for loop'では、 'first for loop'の範囲()への2回目の呼び出しに相当する 'range(len(list))'が呼び出されます。 range()は、 'first for loop'ではなく 'second for loop'からの呼び出しであるかどうかをどのように知っていますか?

+0

'range()' 1 argで、0から始まり、 'arg'までインクリメントするイテレータを返します。最初のforループによって繰り返し呼び出されることはありません。最初のループから抜け出し、新しいループを開始し、0から始まるイテレータを返す 'range()'をもう一度呼び出します。 – AChampion

+0

なぜその出力が得られますか?他のループがオフの場所ではループは開始せず、最初の繰り返しを中断します。 – Li357

+0

あなたのタイトルの質問に対する答えは、使用しているPythonのバージョンによって異なります。 Python 3の 'range'はPython 2とは異なります。また、識別子として 'list'を使用しないでください。これは、組み込みの名前を上書きします。 –

答えて

6

私はあなたがなぜ期待しているのかわかりませんrangeと以前に呼ばれたことを覚えておいてください。クラスは以前の呼び出しに関する状態を保持しません。それは単にあなたが求めるものです。 range(x)を呼び出すたびに、反復処理を行うときに0からx-1までの数字を提供する新しいrangeオブジェクトが返されます。各コールは以前のコールとは独立しています。

あなたが記述している動作を取得するには、各ループでrangeオブジェクトに対して同じイテレータを再利用する必要があります。

Python 3.5.1 (default, Apr 18 2016, 11:46:32) 
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.29)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> l = [1,2,3,4] 
>>> r = range(len(l)) 
>>> for val in r: 
... print(val) 
... break 
... 
0 
>>> for val in r: 
... print(val) 
... break 
... 
0 
>>> i = iter(r) 
>>> for val in i: 
... print(val) 
... break 
... 
0 
>>> for val in i: 
... print(val) 
... break 
... 
1 

あなたはそれがすでにある場合

for x in xs: 
    do_something(x) 

のようなものが

i = iter(xs) 
while True: 
    try: 
     x = next(i) 
    except StopIteration: 
     break 
    do_something(x) 

iterの略であるというイメージが非常にすべての、実際には、イテレータをその引数を返すことができますforループは、ループを繰り返すときに最初から新しいイテレータを返しますr反復可能ではない反復可能です。

+0

各呼び出しは、指定されたシーケンス(0,1、...)で初期化された新しいIteratorオブジェクトを返します。このイテレータは「距離オブジェクト」ですが、正しい用語はイテレータです。 forループは "next"関数を呼び出し、実際にシーケンスを反復処理します。 – DanJ

+0

'range'オブジェクト自体はイテレータではありません。両方のループで 'r'を使うと、それぞれの' for'ループが( 'r .__ iter__'を介して)' range'オブジェクトから新しいイテレータをフェッチするので、依然として質問で出力が生成されます。 – chepner

+2

イテレータは '__next__'メソッドを提供するものですが、* iterable *は' __iter__'メソッドを提供するものです。 'range'は' __iter__'を定義しますが、 '__next__'は定義しません。 ( 'range .__ iter__'は' range_iterator'のインスタンスを返します。これは '__next__'を定義するクラスです)。 – chepner

関連する問題