根据列表列表中的元素复制列表

sha*_*adi 6 python arrays list

我有以下列表:

a = [1, 2, ['c', 'd'], 3, 4, ['e', 'f'], 5, 6]
Run Code Online (Sandbox Code Playgroud)

列表列表的数量a可以有所不同,但是没有.每个列表列表中的元素将保持不变.

例如,如下所示:

a = [1, 2, ['c', 'd'], 3, 4, ['e', 'f'], 5, 6, ['g', 'h'], 7, 8]
Run Code Online (Sandbox Code Playgroud)

要么

a = [1, 2, ['c', 'd', 'e'], 3, 4, ['f', 'g', 'h'], 5, 6, ['i', 'j', 'k'], 7, 8]
Run Code Online (Sandbox Code Playgroud)

所以输入:

a = [1, 2, ['c', 'd'], 3, 4, ['e', 'f'], 5, 6]
Run Code Online (Sandbox Code Playgroud)

我期待以下输出:

[[1, 2, 'c', 3, 4, 'e', 5, 6], [1, 2, 'd', 3, 4, 'f', 5, 6]]
Run Code Online (Sandbox Code Playgroud)

基于没有.列表列表中,列表应该重复,如上面的格式所示.

并为以下输入:

a = [1, 2, ['c', 'd', 'e'], 3, 4, ['f', 'g', 'h'], 5, 6, ['i', 'j', 'k'], 7, 8]
Run Code Online (Sandbox Code Playgroud)

输出应该是:

[[1, 2, 'c', 3, 4, 'f', 5, 6, 'i', 7, 8],
 [1, 2, 'd', 3, 4, 'g', 5, 6, 'j', 7, 8],
 [1, 2, 'e', 3, 4, 'h', 5, 6, 'k', 7, 8]]
Run Code Online (Sandbox Code Playgroud)

到目前为止,我可以做以下事情:

a = [1,2,['c','d'],3,4]

for i in a:
    if type(i) == list:
        t = a.index(i)
        ind = a[t]
        #idx.append(ind)
        a.remove(i)


new = []

for i in ind:
    new1 = []
    for j in a:
        new1.append(j)
    new1.insert(t,i)
    new.append(new1)

new

>> [[1, 2, 'c', 3, 4], [1, 2, 'd', 3, 4]]
Run Code Online (Sandbox Code Playgroud)

如何扩展我编写的代码以实现所需的任务?

Oli*_*çon 7

您的代码的问题t是单个索引,您必须使其成为list索引以考虑多个子列表.

虽然,让我建议替代方案......

带发电机

我们可以将非列表元素转换为重复的生成器,然后使用zip.这利用了这样一个事实:zip只要它耗尽了它的一个参数就会停止迭代.

from itertools import repeat

def expand_list(lst):
    if not any(isinstance(el, list) for el in lst):
        return []
    else:
        return list(zip(*[x if isinstance(x, list) else repeat(x) for x in lst]))
Run Code Online (Sandbox Code Playgroud)

当列表中没有项目本身就是列表时,if语句会处理基本情况.然后返回一个空列表.或者,您也可以将此案例定义为仅返回列表本身.

例:

a = [1, 2, ['c', 'd', 'e'], 3, 4, ['f', 'g', 'h'], 5, 6, ['i', 'j', 'k'], 7, 8]
expand_list(a)
# output:
# [(1, 2, 'c', 3, 4, 'f', 5, 6, 'i', 7, 8),
#  (1, 2, 'd', 3, 4, 'g', 5, 6, 'j', 7, 8),
#  (1, 2, 'e', 3, 4, 'h', 5, 6, 'k', 7, 8)]
Run Code Online (Sandbox Code Playgroud)

有例外

如果您不是生成器,则以下解决方案用于list.pop在遇到列表时选择下一个项目,直到子列表为空.一个IndexError将表明,我们用尽我们的子列表.

import copy

def expand_list(lst):
    if not any(isinstance(el, list) for el in lst):
        return []

    lst = copy.deepcopy(lst)
    output = []

    while True:
        try:
            output.append([x.pop(0) if isinstance(x, list) else x for x in lst])
        except IndexError:
            # Sublists are now empty
            break

    return output
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 1

对于给定的输入列表,收集:

  • 子列表的索引
  • 子列表本身

然后用于在子列表的zip()上创建一个可迭代对象(组合所有第一个元素,然后组合所有第二个元素,等等)。将这些列值插入到原始列表的副本中收集的索引处:

def expand_lists(a):
    indices = []
    sublists = []
    for idx, elem in enumerate(a):
        if isinstance(elem, list):
            indices.append(idx)
            sublists.append(elem)

    results = []
    for combo in zip(*sublists):
        result = a[:]  # shallow copy, because sublists are replaced
        for idx, value in zip(indices, combo):
            result[idx] = value
        results.append(result)

    return results
Run Code Online (Sandbox Code Playgroud)

演示:

>>> expand_lists([1, 2, ['c', 'd'], 3, 4, ['e', 'f'], 5, 6])
[[1, 2, 'c', 3, 4, 'e', 5, 6], [1, 2, 'd', 3, 4, 'f', 5, 6]]
>>> expand_lists([1, 2, ['c', 'd', 'e'], 3, 4, ['f', 'g', 'h'], 5, 6, ['i', 'j', 'k'], 7, 8])
[[1, 2, 'c', 3, 4, 'f', 5, 6, 'i', 7, 8], [1, 2, 'd', 3, 4, 'g', 5, 6, 'j', 7, 8], [1, 2, 'e', 3, 4, 'h', 5, 6, 'k', 7, 8]]
Run Code Online (Sandbox Code Playgroud)