提问人:Alastair909 提问时间:3/26/2023 最后编辑:Andrej KeselyAlastair909 更新时间:3/29/2023 访问量:53
如何缩短输出 Collatz 猜想链号的函数?
How can I shorten a function which outputs the chain numbers of the Collatz conjecture?
问:
此 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]
答:
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 语句。else
elif
return
其次,我不会认可一个有时返回布尔值而返回列表的函数。返回类型应一致:
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))
评论
seq = []
seq