2017-01-11 14 views
0

質問:Python list iterator behavior and next(iterator)iterの中で次の(iter)がPythonでサポートされていますか?

for i in iter: 
    ... 
    next(iter) 

を呼び出すと、forループで先にスキップする効果を持っているという事実を説明します。私が頼りにできる(例えばPEPの中で)これが定義された振る舞いであるのか、それとも単に警告なしに変化する可能性のある実装事故ですか?

答えて

2

iterによって異なります。それは反復可能な、[はい、next(iter)を呼び出すことも進めていきますイテレータのiter()の呼び出しで作成さイテレータだ場合:

>>> it = iter(range(4)) 
>>> for x in it: 
     print(x) 
     _ = next(it) 

0 
2 

それはitイテレータ(だけではなく、任意の反復可能なの)であることが重要ですforループは内部的にそのオブジェクトのiter()も呼び出します。 iter(some_iterator)が呼び出されたときにイテレータ(通常)が返されるので、これは問題なく動作します。

これは良いアイデアですか?一般的に、それは簡単に破ることができるわけではないので:

>>> it = iter(range(3)) 
>>> for x in it: 
     print(x) 
     _ = next(it) 

0 
2 
Traceback (most recent call last): 
    File "<pyshell#21>", line 3, in <module> 
    _ = next(it) 
StopIteration 

が手動ループ内StopIteration例外の例外処理を追加する必要があります。それは非常に面倒です。もちろん、デフォルト値を使用することもできます。 next(it, None)の代わりに、それはすぐに混乱するようになります。特に実際に値を使用していない場合は特にそうです。

誰かが後でイテレータを使用しないことを決めた後、forループで他の繰り返し可能なものがあると(たとえば、リストを使用するコードをリファクタリングして、すべてが壊れてしまうなど)

forループをイテレータを消費する唯一のものにするようにしてください。反復をスキップするかどうかを簡単に判断できるようにロジックを変更します。可能であれば、ループを開始する前に反復可能な文字列を最初ににフィルタリングします。それ以外の場合は、(continueを使用して)ループ内の反復をスキップする条件文を使用します。あなたの例では

>>> it = filter(lambda x: x % 2 == 0, range(3)) 
>>> for x in it: 
     print(x) 

0 
2 

>>> it = range(3) # no need for an iterator here 
>>> for x in it: 
     if x % 2 == 1: 
      continue 
     print(x) 

0 
2 
+0

'範囲(0,3,2)'うん –

+0

@Chris_Randsを十分であろう、私はに依存したくありませんでした'range()'機能はここにあります。私のポイントは、これらの方法はどのような種類の繰り返しでも動作するということです。 – poke

1

forループでは、反復項目の常にnextを呼び出します。

forループ呼び出しの前にnext()を呼び出すと、(次の)項目をスキップする効果があります。

したがって、forが同じメソッド(次へ)を呼び出す限り、プログラムでこれを実装できます。

これまでのところ、3.6でも実装されています。だから、心配する必要はありません。

関連する問題