【问题标题】:Duplicating a list based on elements in its list of lists根据列表列表中的元素复制列表
【发布时间】:2018-05-19 18:39:03
【问题描述】:

我有以下列表:

a = [1, 2, ['c', 'd'], 3, 4, ['e', 'f'], 5, 6]

a 中的列表列表数量可能会有所不同,但没有。每个列表列表中的元素数量将保持不变。

例如,如下所示:

a = [1, 2, ['c', 'd'], 3, 4, ['e', 'f'], 5, 6, ['g', 'h'], 7, 8]

a = [1, 2, ['c', 'd', 'e'], 3, 4, ['f', 'g', 'h'], 5, 6, ['i', 'j', 'k'], 7, 8]

对于输入:

a = [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]]

根据编号。列表的列表,列表应如上述格式所示重复。

对于以下输入:

a = [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]]

到目前为止,我能够做到以下几点:

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

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

【问题讨论】:

    标签: python arrays list


    【解决方案1】:

    您的代码的问题是 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]))
    

    当列表中没有项目本身是列表时,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)]
    

    有例外情况

    如果您不喜欢生成器,以下解决方案使用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
    

    【讨论】:

      【解决方案2】:

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

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

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

      演示:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-26
        • 2018-07-14
        相关资源
        最近更新 更多