Home > database >  Invalid function return
Invalid function return

Time:08-25

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
  • Related