[英]What am I doing wrong regarding iteration
我想打印出呼叫中给定的所有奇数: 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
您的if
分支不会返回任何内容 ,因此您始终raise StopIteration
在此时达到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不知道, 您的代码需要产生那个 。
您的特定问题是,第一个偶数将落入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()
功能,所以我只用它。 除非您的目的是自我教育,否则请自娱自乐。
除非您需要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))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.