将 Python 中的元组转换为嵌套元组

4
有没有一种简单的方法可以转换?
t = ((1,), (1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5))

将以下递归结构追加为前一个元组的元素

(1, (1, 2, (1, 2, 3, (1, 2, 3, 4, (1, 2, 3, 4, 5)))))

这种嵌套有限制吗?我可以拥有1000或10000个这样嵌套的元组吗?
更新: 似乎t的嵌套是无限的(在将递归限制设置为100后尝试了10000次)。
在Windows 7上,Python 3.5的递归限制首先大约为300,但可以像reference中所述那样提高。这与结构t无关,但可能与Python例程访问结果结构的嵌套级别有关。
sys.getrecursionlimit()   # display current recursion level
sys.setrecursionlimit(10000)  # set recursion level to 1000

1
你提到的递归限制与我们可以使用的堆栈帧数有关,即它涉及递归函数调用可以深入多少。这与您可以嵌套元组的深度完全无关,我预计这是无限制的(除了可用内存)。 - wim
太好了!我更新了问题。然而,当我运行David的代码并显示“result”时,我遇到了递归限制问题。请看我的评论给David。 - Oleg Melnikov
3个回答

6
使用 functools.reduce 函数:
>>> from functools import reduce
>>> t = ((1,), (1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5))
>>> reduce(lambda a, b: b + (a,), reversed(t), ())
(1, (1, 2, (1, 2, 3, (1, 2, 3, 4, (1, 2, 3, 4, 5)))))

2
我一直在等待reduce的答案。这是reduce实际上适用的少数几次之一。 - wim
1
@EmilyHill,FYI,接受的答案在空元组中不起作用。 - falsetru
感谢您的关注。空元组并不是一个问题。我必须补充说明functool解决方案也很棒。可惜只能接受一个。 - Oleg Melnikov
1
@EmilyHill,如果是Python 2.x版本,你不需要从functools导入reduce,因为它是内置函数。 - falsetru
1
@falsetru 您的答案对于空元组也不起作用;实际上,甚至不清楚输出应该是什么(None?)。 - David Eisenstat
显示剩余3条评论

0

对于嵌套结构:

def f(t):
    res = t[-1]
    for x in t[-2::-1]:
        res = x + (res,)
    return res

t = ((1,), (1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5))
print f(t)

关于它能有多大,我不知道,但我会假设它取决于您的机器、设置等等...


0

你可以这样做

def convert(t):
    result = t[-1]
    for x in t[-2::-1]:
        result = x + (result,)
    return result

通过t向后迭代。您可能可以构造一个非常深层嵌套的元组,但是您可能会在打印它时遇到麻烦。


我喜欢你的方法,因为它简洁明了,没有使用不必要的工具。谢谢! - Oleg Melnikov
David,这是一个整洁的程序。它可能会受益于将递归限制设置为深度t,否则对于嵌套深度很深的t,它会抛出“RecursionError:maximum recursion depth exceeded while calling a Python object”的错误。尝试使用sys.setrecursionlimit(10),然后执行convert(tuple(tuple(range(k)) for k in range(1,20))) - Oleg Melnikov
1
@EmilyHill 我的代码中没有递归。具体错误是 RuntimeError: maximum recursion depth exceeded while getting the repr of a tuple,这是 Python REPL 尝试并失败地打印结果,正如我预测的那样。如果您将输入的命令更改为通过附加 [:0](以取一个空切片)来丢弃输出,则一切都正常。 - David Eisenstat
David,我认为你代码中的递归是由result = x + (result,)暗示的。它不是显式的递归。看起来falsetru的解决方案也面临着同样的挑战 :) - Oleg Melnikov
@EmilyHill 正如我所说,尝试使用降低的递归限制convert(tuple(tuple(range(k)) for k in range(1,20)))[:0]。错误不在我的代码中。 - David Eisenstat
好的观点。确实,使用100个递归限制,“x=convert(tuple(tuple(range(k)) for k in range(1,200)))”可以正常执行,但在屏幕上打印“x”会抛出错误。感谢澄清。 - Oleg Melnikov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接