递归函数:Syracuse

时间:2017-12-01 20:24:13

标签: python recursion

我想打印一个syracuse序列列表。 我的递归函数只返回[1]

我知道syracuse(n)中的syracuse_sequence是一个局部变量,但我不知道如何返回列表。

import sys

def syracuse(n):
        syracuse_sequence = []
        if n == 1:
                syracuse_sequence.append(round(n))
                print(syracuse_sequence)
                return 0
        elif n % 2 == 0:
                n /= 2
                syracuse_sequence.append(round(n))
                return 1 + syracuse(n)
        else:
                n = (n * 3 ) + 1
                syracuse_sequence.append(round(n))
                return 1 + syracuse(n)

def main(argv):
        n = int(argv[1])
        syracuse(n)
if __name__ == "__main__":
        main(sys.argv)

我期望的结果是:

$python3 syracuse.py 17
[17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]

3 个答案:

答案 0 :(得分:2)

你想要一个循环:

import sys

def syracuse(n):
    syracuse_sequence = [n]
    while True:
        if n == 1:
            print(syracuse_sequence)
            return 0
        elif n % 2 == 0:
            n /= 2
            syracuse_sequence.append(round(n))
            continue
        else:
            n = (n * 3 ) + 1
            syracuse_sequence.append(round(n))
            continue

def main(argv):
    n = int(argv[1])
    syracuse(n)
if __name__ == "__main__":
    main(sys.argv)

这将运行程序,直到它达到1(我认为是你想要的)

这是它为17输出的内容:

Output from 17

希望这有帮助!

答案 1 :(得分:2)

有两种方法可以递归地实现它。一种方法是使累加器成为递归函数的参数。

stat = "quantile"

另一种方法是在每个函数调用中嵌入累加器。

fun = "quantile"

这是因为def syracuse(n, acc=None): if acc is None: acc = [] # why do this? Search "mutable default arguments" # and the side effects that come with! if n == 1: acc.append(n) return acc elif n % 2 == 0: n /= 2 acc.append(n) return syracuse(n, acc) else: n = (n*3) + 1 acc.append(n) return syracuse(n, acc) 。由于每次调用def syracuse(n): if n == 1: return [1] elif n % 2: return [n] + syracuse(n/2) else: return [n] + syracuse(n*3+1) 都会生成另一个与之前一起添加的列表,因此我们得到:

[1] + [2] + [3, 4, 5] == [1, 2, 3, 4, 5]

但请注意,递归是Python特别糟糕的事情。你应该更喜欢这里的迭代。

答案 2 :(得分:0)

使用递归执行此操作的一种方法是传递并返回列表,而不是nn只是列表的最后一个元素。这在整个递归过程中重复使用相同的列表对象,而不是不断地创建新的列表对象,因此具有优于例如内存和性能的优点。亚当·斯密的第二个版本。

def syracuse(seq):
    n = seq[-1]
    if n == 1:            # done
        return seq
    if n % 2:             # odd
        seq.append(n * 3 + 1)
        return syracuse(seq)
    seq.append(n // 2)    # even
    return syracuse(seq)

我还删除了代码中不需要的一些内容,并重新安排了一些内容以简化代码。

要调用它,您必须将n作为单项列表传递:

syracuse([17])

如果您不想传入列表,只需在开头添加测试:

def syracuse(seq):
    if type(seq) is not list:
       seq = [seq]
    n = seq[-1]
    if n == 1:            # done
        return seq
    if n % 2:             # odd
        seq.append(n * 3 + 1)
        return syracuse(seq)
    seq.append(n // 2)    # even
    return syracuse(seq)

或添加辅助功能:

def syracuse2(seq):
    n = seq[-1]
    if n == 1:            # done
        return seq
    if n % 2:             # odd
        seq.append(n * 3 + 1)
        return syracuse2(seq)
    seq.append(n // 2)    # even
    return syracuse2(seq)

def syracuse(n):
    return syracuse2([n])