I have two lists as follows.
l1=[a,b,c,d,e]
l2=[[p,q],[r,s,t]]
How do I create a list of lists from l1 similar to list l2 ?
Desired output: [[a,b],[c,d,e]]
Your help is much appreciated. Thanks!
The following approach will work for arbitrarily nested lists, and doesn't require a deep copy nor an inefficient pop
from the end of the list, making this version linear on the total number of items, instead of quadratic:
def structured_replace(values, nested):
it = iter(values)
def _helper(nested):
return [
_helper(item) if isinstance(item, list) else next(it)
for item in nested
]
return _helper(nested)
a, b, c, d, e = "abcde"
p, q, r, s, t = "pqrst"
l1 = [a,b,c,d,e]
l2 = [[p,q],[r,s,t]]
print(structured_replace(l1, l2))
Also, just for fun, here's an iterative solution:
def structured_replace(values, nested):
it = iter(values)
top_result = []
stack = [(nested, top_result)]
while stack:
item, result = stack.pop()
if isinstance(item, list):
subresult = []
result.append(subresult)
for sub in reversed(item):
stack.append((sub, subresult))
else:
result.append(next(it))
return top_result[0]
Also, here's a breadth-first approach, which we can modify the iterative approach easily and use the standard queue-based approach:
def structured_replace_breadth_first(values, nested):
from collections import deque
it = iter(values)
top_result = []
stack = deque([(nested, top_result)])
while stack:
item, result = stack.popleft()
if isinstance(item, list):
subresult = []
result.append(subresult)
for sub in item:
stack.append((sub, subresult))
else:
result.append(next(it))
return top_result[0]
For the differences:
In [5]: structured_replace('abcdefg', [[1, 2], 3, [4, [5, 6], 7]])
Out[5]: [['a', 'b'], 'c', ['d', ['e', 'f'], 'g']]
In [6]: structured_replace_level_first('abcdefg', [[1, 2], 3, [4, [5, 6], 7]])
Out[6]: [['b', 'c'], 'a', ['d', ['f', 'g'], 'e']]