在Python中递归镜像嵌套元组

时间:2018-01-15 09:44:33

标签: python python-3.x recursion

我试图编写一个输入嵌套元组的函数,并返回一个元组,其中所有元素都向后,包括其他元组中的元素(基本上镜像它)。 所以有了这个输入:

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

它应该返回:

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

我尝试了什么

def mirror(t):
    n = 1
    for i in t:
        if isinstance(i, tuple):
            mirror(i)
        if n == len(t):
            t = list(t)
            t = t[::-1]
            t = tuple(t)
        n += 1
    return t

4 个答案:

答案 0 :(得分:7)

这个问题的棘手在于tuple对象是不可变的。我能想到的一个解决方案是在最终反转结果中递归构建每个部分,然后使用itertools将它们连接在一起。

from itertools import chain

def mirror(data):
    r = []
    for t in reversed(data):
        if isinstance(t, tuple):
            t = mirror(t)
        r.append((t, ))

    return tuple(chain.from_iterable(r))

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

感谢Chris_Rands的改进。

这是一个更简单的解决方案,由PM2 Ring提供 -

def mirror(t):
    return tuple(mirror(u) for u in t[::-1]) if isinstance(t, tuple) else t

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

它使用gen comp。

递归地构建结果元组

答案 1 :(得分:7)

也许我错过了什么,但我认为可以相对简单地完成:

def mirror(data):
    if not isinstance(data, tuple):
        return data
    return tuple(map(mirror, reversed(data)))

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

这将mirror函数应用于元组中的每个元素,并以相反的顺序将它们组合成一个新元组。

答案 2 :(得分:4)

这种类型的结构,列表内部列表,被称为分层结构,其具有整个结构由类似于大结构的小结构组装并且再由更小结构组装的特性。

对树枝进行成像,树枝与整棵树相似,并在树枝上留下。首先要区分树枝和树叶。如果你看到一个分支,你将它视为一个较小的树(这自然形成一个递归)。如果你看到一个假,这意味着你到达结构的尖端,你可以返回它(递归的基本情况)。

从较大的分支到较小的分支(递归中的推论),通常有两种递归方法。第一个是我所做的,将分支左右分开并沿着它们分别前进。另一种方法是将每个分支映射为khelwood所做的。

def mirror(T):
    if not isinstance(T, tuple):
        return T 
    elif T == ():
        return ()
    else:
        return mirror(T[1:]) + (mirror(T[0]),)

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

答案 3 :(得分:0)

无法帮助自己:)

(这当然是一个笑话,但还有逆转数字的额外好处;)

def rev(s, i, acc):
  if i == len(s):
    return acc

  ps = {'(': ')', ')': '('}

  return rev(s, i + 1, s[i] + acc) if not s[i] in ps else rev (s, i + 1, ps[s[i]] + acc)

def funnyMirror(t):
  return eval(rev(str(t), 0, ''))

print funnyMirror(((1, (2, 83)), (4, 5))) # ((5, 4), ((38, 2), 1))