I have 6 lists of lists (sections), sec1
through sec6
. I want to join them in order to form one list.
Example:
sec1 = [[1,2,3],[4,5,6]]
sec2 = [[7,8,9], [6], [1,2]]
If I join these two sections, I should get:
sec_join = [[1,2,3,7,8,9], [1,2,3,6], [1,2,3,1,2], [4,5,6,7,8,9], [4,5,6,6], [4,5,6,1,2]]
Now I have 6 such sections and I want to join them accordingly.
Note: len(sec_join) = len(sec1)*len(sec2)....*len(sec6)
I can do this using 6 for loops
[[[[[[sec_join.append(x1 + x2 + x3 + x4 + x5 + x6) for x1 in sec1] for x2 in sec2] for x3 in sec3] for x4 in sec4] for x5 in sec5] for x6 in sec6]
But the above method is O($n^6$)
. Is it possible to do it in better time complexity?
Note: In my case, the elements of sec1...sec6
are tuples of integers and not integers and hence sorting could be messy.
Edit:
I understand it cant be done in better than O($n^6$)
complexity. Still, are there any "pythonic" ways to do it faster other than 6 for loops & list comrehension? Using any library functions, etc?
I think list concatenation will be faster than going through chain
.
sec_join = sec1
for sec in sec2, sec3, sec4, sec5, sec6:
sec_join = [head + tail
for head in sec_join
for tail in sec]
Could likely be sped up further by combining in different ways, but I'd have to know the actual list sizes.
This might be fastest, minimizing the number of iterations if your lists are about the same size:
sec_join = sec6
for sec in sec5, sec4, sec3, sec2, sec1:
sec_join = [head + tail
for head in sec
for tail in sec_join]
A little benchmark:
134 ms myrtlecat
46 ms Kelly
Code (Try it online!):
from itertools import chain, product
sec1 = [[1,2,3],[4,5,6]]*3
sec2 = [[7,8,9], [6], [1,2]]*3
def Kelly(sec1,sec2,sec3,sec4,sec5,sec6):
sec_join = sec6
for sec in sec5, sec4, sec3, sec2, sec1:
sec_join = [head + tail
for head in sec
for tail in sec_join]
return sec_join
def myrtlecat(sec1,sec2,sec3,sec4,sec5,sec6):
return [list(chain(*x)) for x in product(sec1, sec2, sec3, sec4, sec5, sec6)]
from timeit import *
args = sec1,sec2,sec1,sec2,sec1,sec2
expect = myrtlecat(*args)
result = Kelly(*args)
print(result == expect)
for a in expect, result: print(len(a))
for func in [myrtlecat, Kelly]*3:
t = min(repeat(lambda: func(*args), number=1))
print('%3d ms' % (t * 1e3), func.__name__)