如何缩短输出 Collatz 猜想链号的函数?

How can I shorten a function which outputs the chain numbers of the Collatz conjecture?

提问人:Alastair909 提问时间:3/26/2023 最后编辑:Andrej KeselyAlastair909 更新时间:3/29/2023 访问量:53

问:

此 Python 函数根据 collatz 猜想输出一个列表。这是一个未解决的数学问题,函数将对“n”执行不同的运算,具体取决于它是奇数还是偶数,每次函数重复时,都会将“n”输出到名为“seq”的列表中。最终,一旦数字“16”出现在“链”中,“n”将衰减到终点(“1”)。

我试图使代码尽可能简洁。有什么方法可以缩短功能吗?

这是我的新手 Python 代码:

def collatz(n):

    seq = []
    n = int(n)

    if n == 0:
        return 
    
    elif n == 1:
        return seq + [n]
    
    elif n > 1 == True and n % 2 == 0:
        return seq + [n] + collatz(n/2)
    
    else:
        return seq + [n] + collatz(3*n+1)

print(collatz(7))

这输出

[7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]
Python 递归 Collatz 美学

评论

0赞 quamrana 3/26/2023
是的,您可以删除对 的所有其他引用。该变量在函数中不执行任何操作。seq = []seq

答:

3赞 Jakub Skop 3/26/2023 #1

截至目前,您给出的函数对于负输入和 0 并不完全健壮:我会在下面重写它。不过,我认为你的可读性很强,我不会提倡更简洁:可读性>简洁性几乎总是如此。

def collatz(n):

    seq = []
    n = int(n)

    if n <= 0:
        return False
    
    elif n == 1:
        return seq + [n]
    
    elif n % 2 == 0:
        return seq + [n] + collatz(n/2)
    
    else:
        return seq + [n] + collatz(3*n+1)

print(collatz(7))

如果你真的想要更简洁的代码,可以考虑 @Kelly Bundy 的这个解决方案:

def collatz(n):
    return [1] if n == 1 else [n] + collatz(3*n+1 if n%2 else n//2)

print(collatz(7))

或者,迭代解决方案而不是递归解决方案

def collatz(n):
    seq = [n]
    while n != 1:
        n = 3*n+1 if n%2 else n//2
        seq.append(n)
    return seq

随心所欲地清理您的输入。

评论

0赞 quamrana 3/26/2023
除了 if 应为 : ,否则返回的列表不包含最终的 .if n <= 0:1
0赞 Kelly Bundy 3/26/2023
为什么要进行超复杂的递归调用?
0赞 Kelly Bundy 3/26/2023
特别是因为你谈论可读性:-)
0赞 Jakub Skop 3/26/2023
@KellyBundy 这是一个很好的观点 - 最初使用的递归,我决定遵循套件,但当然迭代解决方案对于大输入来说更健壮,而且速度也更快。我也添加了一个迭代解决方案:)
2赞 Kelly Bundy 3/26/2023
它不是 If 语句。您确实不能在表达式中编写语句。只有表达式。这是一个条件表达式。
0赞 cdlane 3/29/2023 #2

我对当前所选答案的可读性更强的版本有疑问。首先,不需要给定语句的 and 语句。elseelifreturn

其次,我不会认可一个有时返回布尔值而返回列表的函数。返回类型应一致:

def collatz(n):
    if n <= 0:
        return []

    if n == 1:
        return [n]

    if n % 2:
        return [n, *collatz(3 * n + 1)]

    return [n, *collatz(n // 2)]

print(collatz(7))