Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
计算范围内的平方数(python)_Python_Iterator - Fatal编程技术网

计算范围内的平方数(python)

计算范围内的平方数(python),python,iterator,Python,Iterator,我希望能够执行以下代码: for i in Squares(5, 50): print(i) 现在这很容易用循环实现,不过我想用迭代器 因此,我定义了以下类: import math class Squares(object): def __init__(self, start, stop): self.start = start self.stop = stop def __iter__(self): retur

我希望能够执行以下代码:

for i in Squares(5, 50):
      print(i)
现在这很容易用循环实现,不过我想用迭代器

因此,我定义了以下类:

import math

class Squares(object):

    def __init__(self, start, stop):
       self.start = start
       self.stop = stop

    def __iter__(self): 
        return self

    def __next__(self):
        start = self.start
        stop = self.stop
        squareroot = math.sqrt(start)

        if self.start > self.stop:
            raise StopIteration

        if squareroot == math.ceil(squareroot):
            start += 1
但目前,这是返回的
None
无限次。这意味着none必须是,因为
StopIteration
正在执行,即使它不应该执行。我认为我的
if squareroot==math.ceil(squareroot):
条件是正确的,因为我单独测试了它,但我不知道要更改什么以获得我想要的输出。感谢您的帮助

编辑:对于以下代码:

for i in Squares(4, 16):
    print(i)
我预计产出为:

4
9
16

尝试创建生成器函数:

from math import sqrt, ceil

def Squares(start, stop):
    for i in range(start, stop+1):
        sqrti = sqrt(i)
        if sqrti == ceil(sqrti):
            yield i
import math

def squares(lo, hi):
    root = int(math.ceil(lo ** 0.5))
    num = root ** 2
    delta = 2 * root + 1
    while num <= hi:
        yield num
        num += delta
        delta += 2

print list(squares(4, 16))
print list(squares(5, 50))
print list(squares(20, 90))
然后循环它:

for i in Squares(4, 20):
    print i,
提示:

4 9 16

编辑:编辑以匹配方形定义,而不是先前的方形幂(抱歉:p)。将+1添加到范围以匹配OP的问题示例。

我认为您的意思是保持递增开始,直到它到达下一个正方形,而不是仅当它是正方形时才递增:

def __next__(self):
    self.start += 1
    squareroot = math.sqrt(self.start)
    while squareroot != math.ceil(squareroot):
        if self.start > self.stop:
            raise StopIteration
        self.start += 1
        squareroot = math.sqrt(self.start)
最简单的方法是:


import math


class Squares(object):

    def __init__(self, start, stop):
        self._squares = range(start, stop + 1)

    def __iter__(self):
        return self._squares.__iter__()

    def __next__(self):
        if math.sqrt(self._squares.next()) == math.ceil(math.sqrt(self._squares.next())): 
            return math.sqrt(self._squares.next()) 


if __name__ == '__main__':
    for i in Squares(5, 50):
        print i


您可以使用

(n + 1)**2 == n**2 + (2*n + 1)
以下是如何使用生成器函数执行此操作:

from math import sqrt, ceil

def Squares(start, stop):
    for i in range(start, stop+1):
        sqrti = sqrt(i)
        if sqrti == ceil(sqrti):
            yield i
import math

def squares(lo, hi):
    root = int(math.ceil(lo ** 0.5))
    num = root ** 2
    delta = 2 * root + 1
    while num <= hi:
        yield num
        num += delta
        delta += 2

print list(squares(4, 16))
print list(squares(5, 50))
print list(squares(20, 90))
这里有一个等价的迭代器类。我给了它一个
\uuuu repr\uuu
方法,所以如果您打印这个类的实例,它看起来很不错

import math

class Squares(object):
    def __init__(self, start, stop):
        self.start = start
        self.stop = stop
        root = int(math.ceil(start ** 0.5))
        self.num = root ** 2
        self.delta = 2 * root + 1

    def __repr__(self):
        return 'Squares(%d, %d)' % (self.start, self.stop)

    def __iter__(self): 
        return self

    def next(self):
        num = self.num
        if num > self.stop:
            raise StopIteration
        self.num += self.delta
        self.delta += 2
        return num

sq = Squares(4, 16)
print sq
for i in sq:
    print i

print list(Squares(5, 50))
print list(Squares(20, 90))
输出

[4, 9, 16]
[9, 16, 25, 36, 49]
[25, 36, 49, 64, 81]
Squares(4, 16)
4
9
16
[9, 16, 25, 36, 49]
[25, 36, 49, 64, 81]
对于Python3,将
next
方法名称替换为
\uuuuuuuuuu

Python通常的
range
惯例是在达到上限之前停止。要使此代码符合该约定,请在
squares()
生成器中进行更改

while num <= hi:

现在您有了自己的正方形生成器:

gen_sqr.next() #4
gen_sqr.next() #9
list(gen_sqr) #[16]
你可以简单地做到这一点

def squares(start, end): 
return [i**2 for i in range(start, end+1) ]
结果是什么

print(squares(1, 5))
将是:

[1,4,9,16,25]


您期望的O/P是多少?(3,4,5,6,7)?当
start
是一个正方形时,您只会递增
start
。这意味着它会被卡在第一个非正方形上。@Bhargav Rao我刚刚编辑:)也许这里您只需要一个Python生成器,只需使用生成器理解就可以获得一个快速且内存高效的解决方案(见下文)。这是一个生成器:这并不能回答如何使用迭代器查找范围内所有正方形的问题。。。这是一个很好的答案,但回答了另一个问题。@Kittsil我认为它只是指平方迭代器,作为返回给定数字平方幂的迭代器。我编辑了答案,以提供正确的平方定义。这不就是打印所有从5到49的数字吗?我想这就是OP想要的
def squares(start, end): 
return [i**2 for i in range(start, end+1) ]
print(squares(1, 5))