Первые N счастливое число


Я написал кусок кода, чтобы создать список \ФП\$ Счастливые Числа, очень хотелось бы увидеть, как я могу написать это лучше. Более подробную информацию ниже.

#a happy number is defined is found by taking a number, and adding the sum of its digits, and repeating the steps to add the sum of square
#of the resultant digits until we reach 1, if the result never reaches 1 then it is not a happy number

# example: number = 7
# 7^2 = 49
# 4^2 + 9^2 = 16+81 = 97
# 9^2 + 7^2 = 81 + 49 = 130
# 1^2 + 3^2 + 0 = 1+9 = 10
# 1^2 + 0 = 1 HAPPY number
#defining a emtpy list that will be populate as soon as we encounter a happy number
happy_numbers = []
sqdict={str(i):i**2 for i in range(10)}

#lets define our adder
def adder3(num):
    return sum(sqdict[i] for i in str(num))

#now we need to take a number and keep adding until we get a 1 or the loop keeps repeating
# lets define a function for that

def happynum (num, counter):
    i_sum = adder3(num) # storing the value from the adder fucntion to i_sum
    if i_sum == 1: # check for happy number
        happy_numbers.append(number)
        # print("The given number {} is a happy number.".format(number))
        return 1
    else: # we continue to keep splitting and adding until we reach 1 or attain infinite loop
        counter +=1
        if counter > 50:
             # print("The number {} isnt happy :(.".format(number))
            return False
        else:
            happynum(i_sum,counter)

counter = 0 # initializing a counter to keep keep track of the infinite loop if it does reach that.
# user_num = 7
for i in range (0, 1000):
    number = i
    happynum(number, counter)
print(happy_numbers[10])

Приведенный выше код работает хорошо, за то, что я пытаюсь добиться. Однако, я попытался определить счетчик в качестве глобальной переменной, прежде чем все методы, но при вызове метода я не смог прирасти. Он бросил ошибку АА "локальная переменная используется до назначения".

Кроме того, я не уверен, что с помощью цикла for В конце концов, чтобы создать 1000 счастливых чисел является эффективным способом, кажется, несколько ограничивает. Был бы признателен некоторую помощь на этом.



669
3
задан 27 января 2018 в 11:01 Источник Поделиться
Комментарии
1 ответ

Стиль кодирования

Слишком мало белого пространства во многих местах, например


sqdict={str(i):i**2 for i in range(10)}

Этот и другие PEP8 стиль кодирования
нарушений (большинство из них, связанные с расстоянием и слишком длинные строки комментариев)
могут быть обнаружены путем проверки кода PEP8 онлайн.

Ненужные комментарии

Есть некоторые замечания, которые не добавляют информации к коду и могут быть безопасно удалены,
например


#lets define our adder
def adder3(num):

или


i_sum = adder3(num) # storing the value from the adder fucntion to i_sum

Именования


def adder3(num):

Невозможно догадаться по названию функция и что ее цель может быть.
Я бы предложил что-то вроде square_digit_sum.


def happynum (num, counter):

Вот мы знаем, что функция о, что же делать? Вычислить счастливое число,
проверить на счастливое число, ...?

Структура кода:

Глобальная переменная counter = 0 вообще не используется и может быть удален.

Глобальная переменная number = i используется для "запоминания" аргумент
первой вызов рекурсивной happynum функция и функция
(в качестве "побочного эффекта") добавляет к глобальному happy_numbersмассив.
Это чревато ошибками и не очень элегантно.

Я бы предложил для определения функции is_happy вместо этого, которая принимает число и
ограничение рекурсии, и возвращает true или false. Рекурсия лимит по умолчанию может быть
определяется как значение параметра по умолчанию:

def is_happy(num, reclimit=50):
if num == 1:
return True
if reclimit <= 0:
return False
return is_happy(square_digit_sum(num), reclimit - 1)

Отметим также, что нет else: блок нужен, если if: блок
возвращает заявление. Это экономит уровней отступов.

Затем вы можете использовать список понимание

happy_numbers = [num for num in range(1000) if is_happy(num)]

или фильтр

happy_numbers = filter(is_happy, range(1000))

чтобы создать массив с первой 1000 счастливых чисел.

Также это хорошая привычка ставить добавить "главного охранника", так что исходный файл может быть
импортирован как модуль:

if __name__ == "__main__":
happy_numbers = filter(is_happy, range(1000))
print(happy_numbers)

Улучшения производительности:

Вычисление площади цифра суммы может быть немного быстрее, используя целое число
арифметика, без преобразования строк:

def square_digit_sum(num):
sum = 0
while num > 0:
digit = num % 10
sum += digit * digit
num //= 10
return sum

(Это делает sqdict хэш-устар.)

Рекурсия лимит в 50 носит несколько условный характер, и может быть недостаточным для
больших количествах. Возможная альтернатива-запомнить все цифры до сих пор
в наборе:

def is_happy(num):
seen = set()
while num > 1:
if num in seen:
return False
seen.add(num)
num = square_digit_sum(num)
return True

Дополнительные предложения:

Добавить строкой документации комментарии ко всем функциям.

1
ответ дан 28 января 2018 в 02:01 Источник Поделиться