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]