Функция Python, возвращающая None после рекурсии - PullRequest
3 голосов
/ 18 января 2010

Я не могу понять, почему эта функция Python возвращает None, если она вызывает себя рекурсивно.

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

def next_prime(previous):
    if previous % 2 == 0:
        candidate = previous + 1
    else:
    candidate = previous + 2
    print "trying", candidate
    prime = True
    for div in range(2,candidate//2,1):
        if candidate % div == 0:
            prime = False
            print candidate, "is not prime - divisible by", div
            next_prime(candidate)
            break
    if prime is True:
        print candidate, "is prime"
        #return candidate

last = 896576
print "After", last, ", the next prime is..."
next_prime(last)

Это дает:

After 896576 , the next prime is...
trying 896577
896577 is not prime - divisible by 3
trying 896579
896579 is not prime - divisible by 701
trying 896581
896581 is not prime - divisible by 7
trying 896583
896583 is not prime - divisible by 3
trying 896585
896585 is not prime - divisible by 5
trying 896587
896587 is prime

Но если я раскомментирую оператор return, он возвращает значение только в том случае, если первая попытка проста, в противном случае он возвращает None.

Ответы [ 3 ]

6 голосов
/ 18 января 2010

Вы забыли вернуть значение при невозможности найти простое число:

for div in range(2,candidate//2,1):
    if candidate % div == 0:
        prime = False
        print candidate, "is not prime - divisible by", div
        return next_prime(candidate)

Рекурсия здесь не совсем подходит. Это не намного элегантнее, чем простой итеративный подход. Кроме того, вы можете переполнить стек, если попадете в область, где между двумя последовательными простыми числами много простых чисел.

1 голос
/ 18 января 2010

Как уже говорили другие, это не место для рекурсии. Вот пример использования итерации. Я также определил другую функцию, которая проверяет простоту целого числа - я думаю, что это делает код проще.

def is_prime(n):
    """Return True if n is prime."""
    for i in xrange(2, n//2):
        if n%i == 0:
            return False
    return True

def next_prime(n):
    """Returns the next prime number after n."""
    if n % 2 == 0:
        candidate = n + 1
    else:
        candidate = n + 2
    while not is_prime(candidate):
        candidate += 2
    return candidate

if __name__ == '__main__':
    n = 896576
    print next_prime(n)
0 голосов
/ 18 января 2010

Обратите внимание, что вы делаете рекурсивные вызовы функции next_prime, но не возвращаете значение из нее из вызывающей функции.

Заменить строки:

print candidate, "is not prime - divisible by", div
next_prime(candidate)

с

print candidate, "is not prime - divisible by", div
return next_prime(candidate)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...