Unpacking and repacking a tuple (Python 2.x)

I wrote a function that accepts, works, and returns simple, non-nested tuples.

eg:.

myfun((1,2,3,4)):
... -> logic
return (1,2,3,4) -> the numbers can change, but the shape will be the same

Since the logic only works with one-dimensional tuples, it is conceptually the same for each level of nesting. I was wondering if there is a way to convert a nested type tuple ((1,2,(3,)),(4,))into a regular one (1,2,3,4), and then convert it back to ((1,2,(3,)),(4,)).

Basically, I want to unpack a common input tuple, work with it, and then pack the results in the same kind of data.

Is there a pythonic way to accomplish such a task?

Unpacking can probably be resolved with recursion, however, I'm not sure about the "re-packing" part.

+4
3

:

def unpack(parent):
    for child in parent:
        if type(child) == tuple:
            yield from unpack(child)
        else:
            yield child

, .

. , , pythonic, :

def repack(structured, flat):
    output = []
    global flatlist
    flatlist = list(flat)
    for child in structured:
        if type(child) == tuple:
            output.append(repack(child, flatlist))
        else:
            output.append(flatlist.pop(0))

    return tuple(output)

:

nested = ((1, 2, (3,)), (4,))
plain = tuple(unpack(nested))
renested = repack(nested, plain)

, !

+2

:

x = (1,(2,3),(4,(5,6)))
y = (9,8,7,6,5,4)

def map_shape(x, y, start=0):
    if type(x) == tuple:
        l = []
        for item in x:
            mapped, n_item = map_shape(item, y[start:])
            start += n_item
            l.append(mapped)
        return tuple(l), start
    else:
        return y[start], start+1

map_shape(x,y)[0]

:

(9, (8, 7), (6, (5, 4)))
+2

I am posting my version. It uses the same function for flat and restores the list. If flat None, it is smoothed, otherwise it is restored, receiving a set.

import collections


def restructure(original, flat=None):
    for el in original:
        if isinstance(el, collections.Iterable) and not isinstance(el, (str, bytes)):
            if flat:
                yield tuple(restructure(el, flat))
            else:
                yield from restructure(el)
        else:
            yield next(flat) if flat else el


def gen():
    i = 0
    while True:
        yield i
        i += 1


def myfun(iterable):
    flat = tuple(restructure(iterable))
    # your transformation ..
    flat = gen()  # assigning infinite number generator for testing
    return restructure(iterable, flat=iter(flat))


x = (1, (2, 3), (4, (5, 6)))
print(tuple(y for y in myfun(x)))  # (0, (1, 2), (3, (4, 5)))
+1
source

Source: https://habr.com/ru/post/1685052/


All Articles