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

#python #function

Вопрос:

Я попытался изменить имя переменной, думая, что в этом была проблема, но это не исправило ее. Я пытаюсь вычислить аддитивное постоянство и мультипликативное постоянство, а также аддитивные и мультипликативные корни числа, введенные в функцию get_numbers. Для функций additive_calculator и multiplicative_calculator работает то, что я называю первым, но второе дает мне ошибку в операторе печати, в которой говорится, что значение корня, которое я назвал total и total2 в этом случае, дает мне ссылку на ошибку перед назначением. Я понятия не имею, что делать, чтобы исправить эту ошибку. » введите код здесь

 from functools import reduce def get_numbers():  num = (int(input("Please enter an integer(negative integer to quit):")))  nums = [int(a) for a in str(num)]  return(nums)  nums = get_numbers() print(nums)   def additive_calculator(nums):  print("Additive loop")  counter = 0  while len(nums) gt; 1:  for num in nums:  len(nums)  total = 0  total = sum(nums)  list.clear(nums)  nums = [int(a) for a in str(total)]  print("sum:", total)  print(len(nums))  counter = counter   1  print("Additive persistence", counter,",", "Additive Root:", total) print("DONE")      def multiplicative_calculator(nums):  print("multiplicative loop")  counter = 0  while len(nums) gt; 1:  for num in nums:  len(nums)  total2 = 0  total2 = reduce(lambda x, y: x*y,(nums))  list.clear(nums)  nums = [int(a) for a in str(total2)]  print("sum:", total2)  print(len(nums))  counter = counter   1  print("multiplicative persistence", counter,",", "multiplicative Root:", total2) print("DONE")   multiplicative_calculator(nums)  additive_calculator(nums)  

Комментарии:

1. Если введено только одно число, while len(nums) gt; 1 оно никогда не выполняется и, следовательно total (или total2) никогда не назначается.

2. что, если я введу четырехзначное число, например 1234? что же тогда вызовет ошибку? или это будет считаться числом 1? nums = [int(a) для a в str(nums)] преобразует число в строку, разбивает его на отдельные цифры, а затем превращает их обратно в целые числа в списке.

Ответ №1:

Если вы назначаете переменную в любом месте функции, эта переменная считается локальной переменной (если только она не объявлена глобальной или нелокальной). Не имеет значения, действительно ли вы выполняете назначение при запуске функции; достаточно, чтобы в функции был какой-то оператор, который ей присваивает.

Например, в приведенной ниже функции вы присваиваете переменной a значение только в том случае, если аргумент b является истинным, но a все равно остается локальной переменной, если вы ей не присваиваете значение (когда b равно false).

 def f(b):  if b:  a = "foo"  return a   f(True) # -gt; "foo" f(False) # error  

То же самое и с петлями. Если вы назначаете переменную в теле цикла или переменную в for цикле, эта переменная является локальной переменной, даже если вы не выполняете тело цикла. Если вы выполняете тело, переменная назначается, и ее можно безопасно прочитать, но если вы не выполняете тело, переменная не инициализируется, и ее чтение является ошибкой.

 def f(x):  for a in x:  pass  return a   f([1, 2, 3]) # -gt; 3 f([]) # error  

В вашем коде, если nums он пуст, total2 он никогда не присваивается. Это все еще локальная переменная, потому что в коде ей присвоено назначение-не имеет значения, что оператор никогда не выполняется, — но считывание переменной, если вы ей не присвоили, является ошибкой.

Исправление простое: убедитесь, что вы инициализируетесь total2 независимо от того, входите ли вы в тело цикла или нет.

 def multiplicative_calculator(nums):  print("multiplicative loop")  counter = 0  total2 = 0 # move initialisation of total2 here  while len(nums) gt; 1:  # same code as before...  # when you get here, total2 is initialised whether you  # entered the loop or not.  print("multiplicative persistence", counter,  ",", "multiplicative Root:", total2)  

Комментарии:

1. нужно ли мне объявлять второй экземпляр исходного списка nums? потому что теперь мой ответ всегда равен нулю, даже когда этого не должно быть.

2. Мое изменение влияет только на тот случай, когда nums пуст. Тогда функция теперь возвращает ноль. Если он также возвращает ноль, когда этого не должно быть, значит, исходный код неправильно обрабатывает этот случай. Объявление новых переменных вряд ли что-то исправит. Это просто дает новые имена существующим вещам

3. Для меня немного загадочно, что должен делать цикл, но во многих местах он выглядит неправильно. Вы меняете нумерацию, пока повторяете ее. Это никогда не бывает хорошей идеей. Вы умножаете цифры числа, что даст вам ноль, если есть какие-либо нулевые цифры. Внутренняя инициализация total2 ничего не делает, потому что вы перезаписываете ее сразу после этого, и то же самое относится к очистке nums. Я не могу помочь понять, что не так, потому что я понятия не имею, что это должно делать