2017-04-07 5 views
0

イテレータが出力で余分な 'None'を返すのはなぜですか?以下のパラメータ/例では、私は[4]の代わりに[None,4,None]を取得しています。なぜ誰が追加のなしを取得しているのか、どうすれば修正できるのか説明できますか?印刷中の「返品」は一度しか表示されないので、返品元の呼び出し機能に1つの明細を追加する必要があると仮定しています。不要な 'None'を返すPythonイテレータ

コード:

class Prizes(object): 
    def __init__(self,purchase,n,d): 
     self.purchase = purchase 
     self.length = len(purchase) 
     self.i = n-1 
     self.n = n 
     self.d = d 

    def __iter__(self): 
     return self 

    def __next__(self): 
     if self.i < self.length: 
      old = self.i 
      self.i += self.n 
      if (self.purchase[old])%(self.d) == 0: 
       print("returning") 
       return old+1 
     else: 
      raise StopIteration 

def superPrize(purchases, n, d): 
    return list(Prizes(purchases, n, d)) 

purchases = [12, 43, 13, 465, 1, 13] 
n = 2 
d = 3 
print(superPrize(purchases, n, d)) 

出力:明示的なreturn文を持っていない場合

returning 
[None, 4, None] 
+2

'self.purchase [old]%self.d!= 0'の場合、' __next__'は何を返しますか? – vaultah

+0

@userを使用すると、問題の原因を特定するまでコードを単純化することもできます。あなたのモジュロアルゴリズムはあなたの質問についてではありません。 – alexis

+0

'self.i = self.n-1'を' def __iter __(self) 'に設定すると、イテレータは再度イテレーションを行うたびに再設定されます。 – Aaron

答えて

1

コメントの人々が指摘したように、あなたのラインif (self.purchase[old])%(self.d) == 0:は、任意の戻り値を返す関数なしにつながります。戻り値がない場合はNoneが暗黙指定されています。 StopIterationを返却する前にこのテストに合格した次の利用可能な値までリストを継続する方法が必要です。これを行う簡単な方法の1つは、テストが失敗した場合にelse句を追加してself.__next__()を再度呼び出すことです。

def __next__(self): 
     if self.i < self.length: 
      old = self.i 
      self.i += self.n 
      if (self.purchase[old])%(self.d) == 0: 
       print("returning") 
       return old+1 
      else: 
       return self.__next__() 
     else: 
      raise StopIteration 
+0

そうです、私のifステートメントが満たされないときはいつでもNoneを返します。これは@tdelaneyでも説明されています。あなたのソリューションに関しては、間違いなく良い選択肢です。ありがとう – user1179317

+0

@ user1179317彼は1〜2分でパンチに私を打つが、クレジットは本当にボルタに行く。 – Aaron

+0

これはpythonに最大限の再帰制限があるため危険です。私のマシンでは、self.dが約1000の場合、例外が発生します。再帰を使用する場合は、再帰を止めるためのメカニズムが必要です。 – tdelaney

2

機能Noneを返します。 if (self.purchase[old])%(self.d) == 0:が真でない場合、それは__next__で起こります。返す値があるまで、__next__に滞在したいと考えています。

class Prizes(object): 
    def __init__(self,purchase,n,d): 
     self.purchase = purchase 
     self.length = len(purchase) 
     self.i = n-1 
     self.n = n 
     self.d = d 

    def __iter__(self): 
     return self 

    def __next__(self): 
     while self.i < self.length: 
      old = self.i 
      self.i += self.n 
      if (self.purchase[old])%(self.d) == 0: 
       return old+1 
     raise StopIteration 

def superPrize(purchases, n, d): 
    return list(Prizes(purchases, n, d)) 

purchases = [12, 43, 13, 465, 1, 13] 
n = 2 
d = 3 
print(superPrize(purchases, n, d)) 
+0

説明のために大丈夫です。 – user1179317

関連する問題