Параметры функции в Python передаются по значению, а не по ссылке. Если вы передадите число функции, функция получит копию этого номера. Если функция изменяет свой параметр, что изменения не будут видны вне функции:
def foo(y):
y += 1
print("y=", y) # prints 11
x = 10
foo(x)
print("x=", x) # Still 10
В вашем случае, самое прямое исправление сделать в CTR глобальную переменную. Это очень уродливо, потому что вам нужно сбросить глобальное значение обратно до 0, если вы хотите снова вызвать функцию collatz, но я показываю эту альтернативу, чтобы показать, что ваша логика правильная, за исключением бита передачи по ссылке. (Обратите внимание, что функция collatz ничего не возвращает, ответ находится в глобальной переменной).
ctr = 0
def collatz(num):
global ctr
if(num != 1):
ctr+=1
if(num%2==0):
collatz(num/2)
else:
collatz(num*3+1)
ctr = 0
collatz(9)
print(ctr)
Поскольку Python не имеет хвостового-вызов-оптимизации, ваш текущий рекурсивный код аварии с переполнением стека, если последовательность Коллатца больше, чем 1000 шагов (это Питоны по умолчанию лимит стека). Вы можете избежать этой проблемы, используя цикл вместо рекурсии. Это также позволяет избавиться от этой сложной глобальной переменной. Конечный результат является немного более идиоматическим Python, на моем взгляде:
def collats(num):
ctr = 0
while num != 1:
ctr += 1
if num % 2 == 0:
num = num/2
else:
num = 3*num + 1
return ctr
print(collatz(9))
Если вы хотите придерживаться с помощью рекурсивных функций, его обычно чист, чтобы избежать использования изменяемых назначений, как вы пытаетесь сделать. Вместо функций, которые являются «подпрограммами», которые изменяют состояние, превращают их в нечто более близкое к математическим функциям, которые получают значение и возвращают результат, который зависит только от входных данных. Если вы сделаете это, это может быть намного проще рассуждать о рекурсии. Я оставлю это упражнение, но типичный «скелет» рекурсивная функция должна иметь если заявление, которое проверяет для базового случая и рекурсивных случаев:
def collatz(n):
if n == 1:
return 0
else if n % 2 == 0:
# tip: something involving collatz(n/2)
return #???
else:
# tip: something involving collatz(3*n+1)
return #???
, что является предполагаемым результатом и то, что вы хотите добиться с этим? – harshil9968
'ctr = collatz (num // 2, ctr)'. Также вы должны работать с Python 3, а '/ 2' - с плавающей запятой,' // 2' - целочисленное деление. –