Python has an official style-guide, PEP8. It recommends using white-space only where necessary (so the blank line after
def squarefree(n): could go, as could the trailing space) and using four spaces as indentation.
Normally I would consider it best practice for a function like this to return actually
False. Your function returns
False or a truthy value, which also works, but is not as clean. Consider changing it from
return n to
As @Dair mentioned in the comments, depending on your use-case for this, it would be faster to write a sieve that gets all square-free numbers up to some limit.
Starting with the Sieve of Eratosthenes, taken from another of my answers, this could be implemented like this:
Check if n is a square-free number, i.e. is divisible by no other perfect square than 1.
n positive integer to check
n if n is a square-free number
for i in range(2, round(n**0.5) + 1):
if n % (i**2) == 0:
"""Generator that yields all square free numbers less than limit"""
a = [True] * limit
# Needed so we don't mark off multiples of 1^2
a = a = False
for i, is_square_free in enumerate(a):
i2 = i * i
for n in range(i2, limit, i2):
a[n] = False
test1 = [n for n in range(100) if squarefree(n)]
test2 = list(square_free_sieve(100))
assert test1 == test2
When generating all square free numbers up to 100,000, your code needs about 3.5s, while the sieve only takes 0.05s, which is about 70 times faster.