the title is a bit weird but essentially i need to take two lists:
list1 = [['1', '1', '1', '1'], ['2', '2', '2', '2'], ['3', '3', '3', '3']]
list2 = [['a', 'a', 'a'], ['b', 'b', 'b']]
and then alternate between the elements in the sub-lists of the two lists and create sub-lists as elements in a new list whose sub-lists are the alternated elements from above
list3 = [['1', 'a', '1', 'a', '1', 'a', '1'], ['1', 'b', '1', 'b', '1', 'b', '1'], ['2', 'a', '2', 'a', '2', 'a', '2'], ... ]
right now my code is:
def foo(array1, array2):
i = 1
for sublist1 in array1:
for sublist2 in array2:
for val in sublist2:
sublist1.insert(i, val)
i = 2
i = 1
return array1
and I'm getting the output:
[['1', 'a', '1', 'a', '1', 'a', '1', 'b', 'b', 'b'], ['2', 'a', '2', 'a', '2', 'a', '2', 'b', 'b', 'b'], ['3', 'a', '3', 'a', '3', 'a', '3', 'b', 'b', 'b']]
the thing is that I'm working with much smaller lists as a proof of concept right now but the final algorithm will need to be able to do this for lists with millions of sub-lists.
CodePudding user response:
I'd use itertools
for the task:
from itertools import product, zip_longest
list1 = [["1", "1", "1", "1"], ["2", "2", "2", "2"], ["3", "3", "3", "3"]]
list2 = [["a", "a", "a"], ["b", "b", "b"]]
out = []
for c in product(list1, list2):
out.append([v for c in zip_longest(*c) for v in c if v is not None])
print(out)
Prints:
[
["1", "a", "1", "a", "1", "a", "1"],
["1", "b", "1", "b", "1", "b", "1"],
["2", "a", "2", "a", "2", "a", "2"],
["2", "b", "2", "b", "2", "b", "2"],
["3", "a", "3", "a", "3", "a", "3"],
["3", "b", "3", "b", "3", "b", "3"],
]
Note: If there's None
in any of your sub-lists, use other fillvalue=
in itertools.zip_longest
CodePudding user response:
You can use a variation on itertools' roundrobin
:
from itertools import cycle, islice
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
num_active = len(iterables)
nexts = cycle(iter(it).__next__ for it in iterables)
while num_active:
try:
for next in nexts:
yield next()
except StopIteration:
# Remove the iterator we just exhausted from the cycle.
num_active -= 1
nexts = cycle(islice(nexts, num_active))
out = [list(roundrobin(a, b)) for a, b in zip(list1, list2)]
Output:
[['1', 'a', '1', 'a', '1', 'a', '1'], ['2', 'b', '2', 'b', '2', 'b', '2']]
CodePudding user response:
I'd use product
to get the Cartesian product of the two lists, and then zip
and chain them:
result = [list(chain.from_iterable(zip(*p))) for p in product(list1, list2)]
CodePudding user response:
use deepcopy:
from copy import deepcopy
def foo(list1, list2):
ans = []
for L1 in list1:
for L2 in list2:
L3 = deepcopy(L1)
for i, val in enumerate(L2):
L3.insert(i * 2 1, val)
ans.append(L3)
return ans