First, the simplest change to your existing code is to get rid of that nested loop. Just have the for
loop and an if
:
for i in range(1, maximum+1):
if i*i > maximum:
break
print(i*i)
Or just have the while
loop and increment manually:
i = 1
while i*i <= maximum:
print(i*i)
i += 1
One thing: Notice I used range(1, maximum+1)
? Ranges are half-open: range(1, maximum)
gives us all the numbers up to but not including maximum
, and we need to include maximum
itself to have all the numbers up to maximum
squared, in case it's 1. (That's the same reason to use <=
instead of <
in the while
version.
But let’s have a bit more fun. If you had all of the natural numbers:
numbers = itertools.count(1)
… you could turn that into all of the squares:
squares = (i*i for i in numbers)
Don’t worry about the fact that there are an infinite number of them; we’re computing them lazily, and we’re going to stop once we pass maximum
:
smallsquares = itertools.takewhile(lambda n: n<=maximum, squares)
… and now we have a nice finite sequence that we can just print out:
print(*smallsquares)
Or, if you’d prefer if all on one line (in which case you probably also prefer a from itertools import count, takewhile
):
print(*takewhile(lambda n: n<=maximum, (i*i for i in count(1)))
But really, that lambda expression is kind of ugly; maybe (with from functools import partial
and from operator import ge
) it’s more readable like this:
print(*takewhile(partial(ge, maximum), (i*i for i in count(1)))