我想打印出来电中给出的所有奇数:
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
答案 0 :(得分:2)
您的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.low
增加2,并且第一次确保以奇数开头:
def __next__(self):
if self.low > self.high:
raise StopIteration
if self.low % 2 == 0:
self.low += 1 # ensure we get an odd number first
retval = self.low
self.low += 2
return retval
我在这里反转了对StopIteration
条件的测试,以便更清楚地知道当仍然有一个值从迭代中返回时函数总是返回一些东西。
只是为了重新迭代,__next__
总是会返回一些东西,你不能期望它不会返回某些内容,所以它会在 至少返回None
。迭代器不计算。 Python没有去让我们询问结果是1,然后是2,然后是3 。 Python只是询问奇数序列中的下一个值是。在1之后,来了3,但是Python并不知道,你的代码需要产生。
答案 1 :(得分:2)
您的具体问题是,第一个偶数会落到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)
话虽如此,我不确定我是否会像你一样实施它。当你可以将它们组合成一个单独的类时,似乎没有必要有两个单独的类:
class Odds:
def __init__(self, end):
self.curr = -1
self.lim = end
def __next__(self):
self.curr += 2
if self.curr > self.lim:
raise StopIteration
return self.curr
def __iter__(self):
return self
o = Odds(10)
for i in o:
print (i)
此外,通过提供start
和step
值,您可以更加通用:
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()
所做的事情,所以我只是使用它。除非你的意图是自我教育,否则在这种情况下玩得很开心。
答案 2 :(得分:0)
如何使用简单的生成器来实现此目的,除非您将Odds类用于其他目的 -
def odds(num):
for i in range(1, num + 1):
if i % 2 != 0:
yield i
print(list(odds(11)))
如果您确实想要出于特定原因使用课程Odds
-
class Odds:
def __init__(self, num):
self.high = num
def __iter__(self):
return odds(self.high)
print(list(Odds(10))