簡體   English   中英

關於迭代我做錯了什么

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM