关于迭代,我做错了什么

2024-04-29 07:41:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我想把电话里所有的单数都打印出来: o = Odds(10),输出应该是1, 3, 5, 7, 9,但我在注释区域做了一些错误,它应该相对简单,但我看不到它。在

class Odds:
    def __init__(self, arg):
        self.num = arg

    def __iter__(self):
        return OddsIterator(self.num)

class OddsIterator:
    def __init__(self, arg):
        self.high = arg
        self.low = 1

    def __next__(self):
        if self.low <= self.high:
            if (self.low % 2) == 0: #somethings wrong around here
                self.low += 1 
            else:
                self.low += 1
                return self.low - 1
        raise StopIteration

Tags: self区域returnifinitdefargnum
3条回答

使用一个简单的生成器来实现这个目的怎么样,除非你需要其他目的的赔率类-

def odds(num):
    for i in range(1, num + 1):
        if i % 2 != 0:
            yield i

print(list(odds(11)))

如果您确实出于特定原因想使用类Odds

^{pr2}$

您的具体问题是,第一个偶数将落到StopIteration行,使您的序列相当短:{ 1 }。在

在我看来,生成所有奇数应该要容易得多。从-1开始,然后在每次呼叫时:

  • 加两个。
  • 如果太高了,停下来。
  • 否则返回当前值。

可通过以下方式实现:

class Odds:
    def __init__(self, arg):
        self.num = arg

    def __iter__(self):
        return OddsIterator(self.num)

class OddsIterator:
    def __init__(self, arg):
        self.high = arg
        self.curr = -1

    def __next__(self):
        self.curr += 2
        if self.curr > self.high:
            raise StopIteration
        return self.curr

o = Odds(10)
for i in o:
    print (i)

话虽如此,我不确定我是否会像你那样执行它。当您可以将两个独立的类合并为一个类时,似乎没有必要使用它们:

^{pr2}$

此外,还可以通过提供startstep值使其更通用:

class XFor:
    def __init__(self, start, end, step):
        self.curr = start - step
        self.lim = end
        self.step = step

    def __next__(self):
        self.curr += self.step
        if self.curr > self.lim:
            raise StopIteration
        return self.curr

    def __iter__(self):
        return self

o = XFor(1,10,2)
for i in o:
    print (i)

尽管它很危险地侵犯了range()的功能,所以我还是用它。除非你的目的是自我教育,在这种情况下要玩得开心。在

您的if分支没有返回任何,因此您总是在此时到达raise StopIteration。假设low是2,high是10:

if self.low <= self.high:  # true, 2 <= 10
    if (self.low % 2) == 0:  # true, 2 is even
        self.low += 1 
    # else branch is skipped, so we come to the next line
raise StopIteration  # iterator ends

您需要在__next__中创建更大的步骤,因为该方法总是返回一些东西。当一个数字是偶数时,您不必返回,而是需要返回序列中的下一个数字,因此每次递增self.low2,第一次请确保从奇数开始:

^{pr2}$

我在这里对StopIteration条件进行了反向测试,以便更清楚地表明,当仍有值可从iterable返回时,函数总是返回某些内容。在

只是为了重新迭代,__next__总是返回一些东西,你不能期望它不返回某些东西,所以它至少会返回None。迭代器不计数。Python不去让我们先询问1的结果,然后是2的结果,然后是3的结果。Python只询问奇数序列中的下一个值是什么。1之后是3,但是Python不知道,您的代码需要生成它。在

相关问题 更多 >