Reputation: 277
Assume that my list is:
[ [1,2,3,4], [ [[5], [6]], [7] ]]
After unpack, I want to get [1,2,3,4], [5], [6], [7]
How to do it with low time complexity?
Upvotes: 1
Views: 1056
Reputation: 18628
You can just recursively check for good lists : good lists are those which don't contain lists. Each list is visited one time only.
def prettyflat(ll):
pf=[]
def good(ll):
isgood = isinstance(ll,list) and all([not good(l) for l in ll])
if isgood : u.append(ll)
return isgood
good(ll)
return pf
Output:[[1, 2, 3, 4], [5], [6], [7]]
Upvotes: 0
Reputation: 304137
Another way using regex:
>>> import re
>>> x = [[1, 2, 3, 4], [[[5], [6]], [7]]]
>>> eval(re.sub(r'([][])\1+', '\\1', str(x)))
([1, 2, 3, 4], [5], [6], [7])
@TigerhawkT3's answer is faster for this x
, 28.9 µs per loop vs 41.8 µs per loop
so just for fun
import json
json.loads(re.sub(r'([][])\1+', '\\1', str(x)))
puts the regex back to 22.1 µs per loop
Upvotes: 2
Reputation: 7268
You can try :
>>> final_list = []
>>> def make_single(input_list):
final_list_inside = []
for i in input_list:
if any(isinstance(el, list) for el in input_list):
make_single(i)
else:
final_list_inside.append(i)
if(len(final_list_inside) != 0):
final_list.append(final_list_inside)
>>> make_single([[1, 2, 3, 4], [[[5], [6]], [7]]])
>>> final_list
[[1, 2, 3, 4], [5], [6], [7]]
Upvotes: 0
Reputation: 49320
The linked duplicate flattens an iterable completely. You just need a slight tweak to make the process stop one step earlier:
import collections
def flattish(l):
for el in l:
if isinstance(el, collections.Iterable) and not isinstance(el, str):
if any(isinstance(e, collections.Iterable) for e in el):
for sub in flattish(el):
yield sub
else:
yield el
else:
yield [el]
The any(...
will check if that iterable contains any iterables. This will flatten something like [1, [2, 3]]
, but leave [5]
as-is. Additionally, the yield [el]
ensures that any non-iterables will be contained in a list
, so your result will be a list
that contains only list
s, some of which may have only a single element.
Upvotes: 3
Reputation: 67968
You can try using re
.
import re
x=[ [1,2,3,4], [ [[5], [6]], [7] ]]
print map(lambda x:map(int,re.findall(r"\d+(?=.*\])",x)),re.findall(r"\[[^\[\]]*\]",str(x)))
Output:[[1, 2, 3, 4], [5], [6], [7]]
Upvotes: 0