使用元素创建列表,这些元素是子列表,这些子列表在来自其他两个列表的子列表中的元素之间交替

create list with elements which are sublists that alternate between elements in sublists from two other lists

提问人:crxunch 提问时间:8/13/2022 最后编辑:Mureinikcrxunch 更新时间:8/14/2022 访问量:75

问:

标题有点奇怪,但基本上我需要列出两个列表:

list1 = [['1', '1', '1', '1'], ['2', '2', '2', '2'], ['3', '3', '3', '3']]
list2 = [['a', 'a', 'a'], ['b', 'b', 'b']]

然后在两个列表的子列表中的元素之间交替,并将子列表创建为新列表中的元素,该列表的子列表是上面的替代元素

list3 = [['1', 'a', '1', 'a', '1', 'a', '1'], ['1', 'b', '1', 'b', '1', 'b', '1'], ['2', 'a', '2', 'a', '2', 'a', '2'], ... ]

现在我的代码是:

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

我得到的是输出:

[['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']]

问题是,我现在正在使用更小的列表作为概念证明,但最终算法需要能够为具有数百万个子列表的列表执行此操作。

Python 算法 list-comprehension nested-lists

评论


答:

1赞 Andrej Kesely 8/14/2022 #1

我会用于这项任务:itertools

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)

指纹:

[
    ["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"],
]

注意:如果任何子列表中有,请在 itertools.zip_longest 中使用其他Nonefillvalue=

1赞 mozway 8/14/2022 #2

您可以使用 itertools 的轮询变体:

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)]

输出:

[['1', 'a', '1', 'a', '1', 'a', '1'], ['2', 'b', '2', 'b', '2', 'b', '2']]

评论

0赞 Daniel Hao 8/14/2022
也许只是 pip install more_itertools 然后使用它。
1赞 Mureinik 8/14/2022 #3

我用来获取两个列表的笛卡尔乘积,然后将它们链接起来:productzip

result = [list(chain.from_iterable(zip(*p))) for p in product(list1, list2)]
0赞 mehrh8 8/14/2022 #4

使用 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