[英]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.