Home > Mobile >  Apply the nested shape of one list on another flat list
Apply the nested shape of one list on another flat list

Time:07-20

I have two lists:

A: [[0, 1], [2, [3]], 4]

B: [5, 6, 7, 8, 9]

I wish list B could have the same shape with list A: [5, 6, 7, 8, 9] => [[5, 6], [7, [8]], 9]

So list A and list B have the same dimension/shape:

A: [[0, 1], [2, [3]], 4]

B: [[5, 6], [7, [8]], 9]

Consider about time complexity, I hope there is a way of O(n) if possible.

CodePudding user response:

Assuming the number of items is identical, you could use a recursive function and an iterator:

A = [[0, 1], [2, [3]], 4]
B = [5, 6, 7, 8, 9]

def copy_shape(l, other):
    if isinstance(other, list):
        other = iter(other)
    if isinstance(l, list):
        return [copy_shape(x, other) for x in l]
    else:
        return next(other)
    
out = copy_shape(A, B)

output: [[5, 6], [7, [8]], 9]

NB. the complexity is O(n). You can also use if hasattr(other, '__len__') or if not hasattr(other, '__next__') in place of if isinstance(other, list) to generalize to other iterables (except iterator).

CodePudding user response:

A one-line variant of @Mozway's idea, using a list comprehension:

A = [[0, 1], [2, [3]], 4]
B = [5, 6, 7, 8, 9]


def un_flatten(t, d):
    return [un_flatten(e, d) if isinstance(e, list) else next(d) for e in t]


match = un_flatten(A, iter(B))
print(match)

Output

[[5, 6], [7, [8]], 9]

Note that it requires to convert the list B to an iterator. The complexity is O(n).

CodePudding user response:

Here is another way with strings and eval -

a = [[0, 1], [2, [3]], 4]
b = [5, 6, 7, 8, 9]

s = ''
i = 0
for char in str(a):
    if char.isdigit(): # or you can use re.match(r'\w ', char) 
        s  = str(b[i])
        i  = 1
    else:
        s  = char

out_b = eval(s)

Output

[[5, 6], [7, [8]], 9]
  • Related