This is my code, why when i print(is_happy(13)) i got True, but in the result of happy_numbers i don't get 13 and many correct numbers?
def is_happy(n, result = []):
next_number = sum(map(lambda x: int(x) ** 2, str(n)))
if next_number == 1:
return True
elif next_number in result:
return False
else:
result.append(next_number)
return is_happy(next_number)
def happy_numbers(n):
result = []
for i in range(1, n 1):
if is_happy(i):
result.append(i)
return result
CodePudding user response:
The issue is that you are using a mutable default argument in is_happy(n, result=[])
. This means that the result
won't start as an empty list every time it's run but rather will keep its old results.
To counter this, I'd remove the default argument and explicitly pass the array:
def is_happy(n, result):
# all the stuff you already had
return is_happy(next_number, result)
and in the other function
if is_happy(i, []):
CodePudding user response:
Generators make your programs easier to write -
def is_happy(n, seen = set()):
if n == 1:
return True
elif n in seen:
return False
else:
return is_happy(sum(x ** 2 for x in digits(n)), seen | {n})
def digits(n):
if n < 10:
yield n
else:
yield from digits(n // 10)
yield n % 10
def happy_numbers(n):
for x in range(n):
if is_happy(x):
yield x
print(list(happy_numbers(100)))
is_happy
can be optimized with lru_cache -
from functools import lru_cache
seen = set()
@lru_cache
def is_happy(n):
if n == 1:
return True
elif n in seen:
return False
else:
seen.add(n)
answer = is_happy(sum(x ** 2 for x in digits(n)))
seen.remove(n)
return answer
print(list(happy_numbers(10000)))
before optimization | with LRU cache | |
---|---|---|
real | 1,303 ms | 284 ms |
user | 470 ms | 118 ms |
sys | 19 ms | 13 ms |