Home > database >  create list with elements which are sublists that alternate between elements in sublists from two ot
create list with elements which are sublists that alternate between elements in sublists from two ot

Time:08-14

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
  • Related