我试图编写一个函数,该函数输入一个嵌套元组并返回一个元组,其中所有元素都向后,包括其他元组中的那些元素(基本上镜像它(。因此,使用此输入:
((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
也许我错过了一些东西,但我认为可以相对简单地完成:
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
函数应用于元组中的每个元素,并将它们以相反的顺序组合成一个新元组。
这个问题的棘手之处在于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环提供 -
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))
它以递归方式构建结果元组,但使用生成复合。
这种类型的结构,列表内的列表,称为分层结构,它具有整个结构由类似于大结构的小结构组装的特性,并且再次由更小的结构组装。
想象一棵树的树枝类似于整棵树,树尖有叶子。第一件事是区分树枝和叶子。如果你看到一个分支,你把它当作一棵较小的树(这自然会形成递归(。如果你看到一个叶子,这意味着你到达结构的顶端,你可以返回它(递归中的基本大小写(。
要从较大的分支到较小的分支(递归中的演绎(,通常有两种递归方法。第一个是我所做的,将树枝分成左右两部分,然后沿着它们中的每一个。另一种方法是在每个分支上绘制地图,就像 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))))
情不自禁地:)
(这当然是一个笑话,但有一个额外的好处,那就是反转数字;)
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))