El iterador de Python devuelve el ‘Ninguno’ no deseado

¿Por qué mi iterador está devolviendo ‘Ninguno’ extra en la salida? Para los parámetros / ejemplo a continuación, obtengo [None,4,None] lugar del deseado [4] ¿Alguien puede explicar por qué obtengo el Extra extra y cómo puedo solucionarlo? La impresión ‘regresando’ solo aparece una vez, por lo que supongo que solo se debe agregar un elemento a la función de callbacks.

código:

 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)) 

Salida:

 returning [None, 4, None] 

Como lo señaló la gente en los comentarios, su línea if (self.purchase[old])%(self.d) == 0: lleva a la función a regresar sin ningún valor de retorno. Si no hay un valor de retorno proporcionado, None está implícito. Necesita alguna forma de continuar a través de su lista hasta el siguiente valor disponible que pasa esta prueba antes de regresar o elevar StopIteration . Una forma fácil de hacer esto es simplemente agregar una cláusula else adicional para llamarse self.__next__() nuevamente si la prueba falla.

 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 

Las funciones devuelven None si no tiene una statement de return explícita. Eso es lo que sucede en __next__ cuando if (self.purchase[old])%(self.d) == 0: no es cierto. Desea permanecer en su __next__ hasta que tenga un valor para devolver.

 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))