Python迭代器返回不需要的'无'

时间:2017-04-07 20:23:36

标签: python iterator

为什么我的迭代器在输出中返回额外的'None'。对于下面的参数/示例,我得到的是[None,4,None]而不是所需的[4]任何人都可以解释为什么我会获得额外的无以及如何修复它?打印出来的'返回'只出现一次所以我假设只有一个项目应该附加到返回的调用函数。

代码:

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

输出:

returning
[None, 4, None]

2 个答案:

答案 0 :(得分:2)

如果您没有明确的None语句,函数将返回return。当__next__不正确时,if (self.purchase[old])%(self.d) == 0:会发生这种情况。您希望留在__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))

答案 1 :(得分:1)

正如评论中的人所指出的那样,您的行if (self.purchase[old])%(self.d) == 0:会导致返回的函数没有任何返回值。如果没有提供返回值,则隐含None。在返回或引发StopIteration之前,您需要某种方式继续通过列表到达通过此测试的下一个可用值。一种简单的方法是在测试失败时添加额外的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