Problem:
Write a function named "unflatten" which takes a list as an argument
and constructs a nested list.
The format of the argument list is as follows:
An integer item indicates a start of a nested list Non-integer items
will be the content of the nested list For instance,
[2, 'a', 3, 'b', 'c', 'd'] is converted to ['a', ['b', 'c', 'd']] The
first number, 2, indicates that the upper list will contain 2 items.
'a' is the first item of this upper list. The number 3 indicates a
start of a new sub-list which contains 3 items.
Sample Run:
>>> unflatten([2, 'x', 'y'])
['x', 'y']
>>> unflatten([ 3, "a", "b", 3, "t", "y", "u" ])
['a', 'b', ['t', 'y', 'u']]
>>> unflatten([ 4, "a", "b", 3, "c", "d", 2, "x", "y", 2, "w" , 3, "t", "y", "u" ])
['a', 'b', ['c', 'd', ['x', 'y']], ['w', ['t', 'y', 'u']]]
I have done a simple recursion. Here is my code:
def unflatten(LIST):
if not len(LIST):
return []
elif isinstance(LIST[0], int):
return [unflatten(LIST[1:])]
else:
return [LIST[0]] + unflatten(LIST[1:])
>>> unflatten([ 4, "a", "b", 3, "c", "d", 2, "x", "y", 2, "w" , 3, "t", "y", "u" ])
[['a', 'b', ['c', 'd', ['x', 'y', ['w', ['t', 'y', 'u']]]]]]
Now as you can see, lengths of lists are not controlled in my basic recursion, so it simply ends all the lists at the end.
I don't know how I can track the lengths recursively, or maybe iteratively. I'd be glad if you suggest a way doing this without importing any modules.
解决方案
One way to keep track of the position is by returning it. In the code below I use a helper function that returns the partially-built unflattened list as well as the current index in the flattened list.
def unflatten(l):
def helper(l, start):
if isinstance(l[start], int):
ret = []
start += 1
for _ in range(l[start - 1]):
sub, start = helper(l, start)
ret.append(sub)
return ret, start
else:
return l[start], start + 1
return helper(l, 0)[0]
print unflatten([2, 'x', 'y'])
print unflatten([ 3, "a", "b", 3, "t", "y", "u" ])
print unflatten([ 4, "a", "b", 3, "c", "d", 2, "x", "y", 2, "w" , 3, "t", "y", "u" ])