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

时间:2018-05-19 18:39:04

标签: python arrays list

我有以下列表:

object Rextester extends App {
    println("Hello, World!3")
 }

trait Dep[C]{
  type A
  type B
}

trait View1
trait View2


object Dep{

  type Aux[C0, A0, B0]=  Dep[C0] {type A=A0; type B= B0}

  implicit object DepInstanceView1  extends  Dep[View1] {
    type A=String
    type B=Int
  } 

  implicit object DepInstanceView2  extends  Dep[View2] {
    type A=String
    type B=String
  } 
}

trait ServerSideFun[C]
{
   def f[A,B] (a:A)(implicit aux:Dep.Aux[C,A,B]):B
}


object ServerSideFun {
  implicit object View1Conv extends ServerSideFun[View1]{
    def f[A, B] (a:A)(implicit aux:Dep.Aux[View1,A,B]):B = 42
  }

  implicit object View2Conv extends ServerSideFun[View2]{
    def f[A, B] (a:A)(implicit aux:Dep.Aux[View2,A,B]):B = "42"
  }
}



object ServerSideFunAlternativeImplementation {
  implicit object View1Conv extends ServerSideFun[View1]{
    def f[A, B] (a:A)(implicit aux:Dep.Aux[View1,A,B]):B = 43
  }

  implicit object View2Conv extends ServerSideFun[View2]{
    def f[A, B] (a:A)(implicit aux:Dep.Aux[View2,A,B]):B = "43"
  }

}

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

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

2 个答案:

答案 0 :(得分: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]))

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

答案 1 :(得分:1)

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

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

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

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