I was trying to write a function that inputs a nested tuple and returns a tuple where all the elements are backwards, including those elements in other tuples (basically mirrors it). So with this input:
((1, (2, 3)), (4, 5))
It should return:
((5, 4), ((3, 2), 1))
What I tried
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
The trickiness of this problem lies in the fact that tuple
objects are immutable. One solution I can think of is recursively building each piece in the final reversed result, and then using itertools
to join them together.
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))
Thanks to Chris_Rands for the improvement.
Here's a simpler solution, courtesy 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))
It builds the result tuple recursively but using a gen comp.
Maybe I'm missing something, but I think it can be done relatively simply:
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))
This applies the mirror
function to every element in the tuple, combining them into one new tuple in reverse order.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With