在交互链表

时间:2017-09-29 03:44:57

标签: python python-3.x list loops

我有一个链表,我在一个范围内迭代并返回所有可以在此范围内表示为整数的平方数。而不仅仅返回可以对其执行的数字将返回None,例如9, None, None...,16, None, None..., 25我希望它只返回9, 16, 25 etc etc

class Squares:
    def __init__(self, start, end):
        self.__start = start - 1
        self.__end = end -1

    def __iter__(self):
        return SquareIterator(self.__start, self.__end)

class SquareIterator:
    def __init__(self, start, end): 
        self.__current = start
        self.__step = 1
        self.__end = end

    def __next__(self):
        if self.__current > self.__end:
            raise StopIteration 
        else:
            self.__current += self.__step 
        x = self.__current - self.__step + 1
        self.__current - self.__step + 1
        if str(x).isdigit() and math.sqrt(x) % 1 == 0:
            return x

2 个答案:

答案 0 :(得分:1)

您需要让__next__函数继续循环,直到达到目标值:

def __next__(self):
    # We're just going to keep looping. Loop breaking logic is below.
    while True:
        # out of bounds
        if self.__current > self.__end:
             raise StopIteration

        # We need to get the current value
        x = self.__current
        # increase the state *after* grabbing it for test
        self.__current += self.__step 

        # Test the value stored above
        if math.sqrt(x) % 1 == 0:
             return x

你应该存储x,然后递增的原因是,无论如何你都必须增加,即使你没有完美的正方形。

答案 1 :(得分:1)

目前还不清楚为什么让事情复杂化;有一个简单的方法:

import math

class Squares:
    def __init__(self, start, end):
        self.__start = start
        self.__end = end
        self.__step = 1

    def __iter__(self):
        for x in range(self.__start, self.__end, self.__step):
            if math.sqrt(x) % 1 == 0:
                yield x

s = Squares(0, 100)
for sq in s:
    print(sq, end=' ')

输出:

0 1 4 9 16 25 36 49 64 81 

来自评论:

  

请注意,避免专用可能会容易得多   迭代器类,只为Squares实现__iter__作为生成器   功能。显式__next__涉及各种低效状态   Python管理不善,并且不容易理解;   __iter__作为生成函数通常非常简单;每当你达到收益时,它就像__next__的回报,但都是   你的状态是本地功能,没有涉及特殊对象(发电机   照顾保存和恢复当地的状态)。 - ShadowRanger>

  

它可能甚至不需要Squares课程。发电机功能   命名广场将做所需的事情;传递它开始,停止和步骤   将它们用作局部变量,而不是某些属性   不必要的自我这个班级唯一真正的优势就是它可以   重复迭代而不重建它,这可能是不常见的用法   情况下

def squares_from(start, stop, step=1):
    """returns a generator function for the perfect squares 
    in the range comprised between start and stop, iterated over using step=step
    """
    for x in range(start, stop, step):
        if math.sqrt(x) % 1 == 0:
            yield x

for sq in squares_from(0, 100):
    print(sq, end=' ')