我希望能够执行以下代码:
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
。这意味着必须是因为StopIteration
正在被执行,即使它不应该被执行。我认为我的if squareroot == math.ceil(squareroot):
条件是正确的,因为我单独测试了它,但是我无法弄清楚要改变什么来获得我想要的输出。任何帮助表示赞赏。
编辑:对于代码如:
for i in Squares(4, 16):
print(i)
我希望输出为:
4
9
16
答案 0 :(得分:3)
尝试创建生成器函数:
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
然后循环它:
for i in Squares(4, 20):
print i,
提示:
4 9 16
编辑:编辑以匹配方形定义,而不是之前的平方功率(抱歉:P)。在范围中添加+1以匹配OP的问题示例。
答案 1 :(得分:2)
我认为你的意思是继续递增直到它到达下一个方格,而不是仅当它是一个正方形时才增加它:
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)
答案 2 :(得分:2)
您可以简单地做到这一点
def squares(start, end):
return [i**2 for i in range(start, end+1) ]
所以结果
print(squares(1, 5))
将是:
[1、4、9、16、25]
答案 3 :(得分:1)
您可以使用
简化算术(n + 1)**2 == n**2 + (2*n + 1)
以下是使用生成器函数的方法:
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))
<强>输出强>
[4, 9, 16]
[9, 16, 25, 36, 49]
[25, 36, 49, 64, 81]
这是一个等效的迭代器类。我已经给它一个__repr__
方法,所以如果你打印这个类的实例它看起来不错。
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))
<强>输出强>
Squares(4, 16)
4
9
16
[9, 16, 25, 36, 49]
[25, 36, 49, 64, 81]
对于Python 3,将next
方法名称替换为__next__
。
通常的Python range
约定是在达到上限之前停止。要使此代码符合该约定,请在squares()
生成器更改
while num <= hi:
到
while num < hi:
并在Squares()
课程中,更改
if num > self.stop:
到
if num >= self.stop:
答案 4 :(得分:0)
最简单的是:
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
答案 5 :(得分:0)
from math import ceil, sqrt
start,stop = 4,16
gen_sqr = ( i for i in range( start, stop +1) if sqrt(i) == ceil( sqrt(i)) )
现在你有了自己的方块生成器:
gen_sqr.next() #4
gen_sqr.next() #9
list(gen_sqr) #[16]