【问题标题】:Insert items from list to another list every n positions每隔 n 个位置将列表中的项目插入另一个列表
【发布时间】:2019-10-10 16:31:03
【问题描述】:

我有以下清单。

vector = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
inserted_elements = [2, 2, 2, 2, 2]

我想通过插入每两个元素来获得以下内容。

output = [1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]

不仅是 Python 列表,使用 numpy 数组的答案也很好。

【问题讨论】:

    标签: python list numpy


    【解决方案1】:

    这是一种基于itertools 的方法,它也适用于从一个列表插入到另一个列表的任意数量的元素。为此,我定义了一个生成器函数,它会将 l2 中的元素插入到 l1 中,每个 i 项:

    def insert_every_n(l1, l2, k):
        i1, i2 = iter(l1), iter(l2)
        while True:
            try:
                yield from islice(i1, k)
                yield next(i2)
            except StopIteration:
                return
    

    这通过使用itertools.islice 在每次迭代中从迭代器l1 产生最多i 项来工作。使用yield from,我们将产生与切片迭代中的一样多的项目,因此迭代会耗尽,(for v in g: yield v 的快捷方式)。

    最后,我们可以用try/expect 包装yield 语句以捕获StopIteration 警告。


    让我们尝试建议的示例:

    vector = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    inserted_elements = [2, 2, 2, 2, 2]
    
    list(insert_every_n(vector, inserted_elements, k=2))
    # [1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]
    

    如果我们想每 3 个项目添加一个 l2 项目:

    vector = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    inserted_elements = [2, 2, 2, 2]
    
    list(insert_every_n(vector, inserted_elements, k=3))
    # [1, 2, 3, 2, 4, 5, 6, 2, 7, 8, 9, 2, 10, 2]
    

    【讨论】:

      【解决方案2】:

      numpy 数组步骤:

      1.

      >>> a=np.reshape(np.matrix([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),(5, 2))
      >>> a
      matrix([[ 1,  2],
              [ 3,  4],
              [ 5,  6],
              [ 7,  8],
              [ 9, 10]])
      

      2.

      >>> b=np.reshape(np.matrix([2, 2, 2, 2, 2]),(5, 1))
      >>> b
      matrix([[2],
              [2],
              [2],
              [2],
              [2]])
      

      3.

      >>> M = np.append(a, b, axis=1)
      >>> M
      matrix([[ 1,  2,  2],
              [ 3,  4,  2],
              [ 5,  6,  2],
              [ 7,  8,  2],
              [ 9, 10,  2]])
      

      4.

      >>> result=np.array(M).flatten()
      >>> result
      array([ 1,  2,  2,  3,  4,  2,  5,  6,  2,  7,  8,  2,  9, 10,  2])
      

      【讨论】:

        【解决方案3】:

        传统的 for 循环方法可能如下所示,您从 vector 中选择 2 个元素,从 inserted_elements 中选择 1 个元素,然后创建 output 列表

        vector = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        inserted_elements = [2, 2, 2, 2, 2]
        
        output = []
        
        #Pick two elements from vector and one element from inserted_elements and add it to output list
        for idx in range(0,len(vector),2):
        
            output.extend(vector[idx:idx+2] + [inserted_elements[int(idx/2)]])
        
        print(output)
        

        列表理解中的相同内容将是

        output = [ v for idx in range(0,len(vector),2) for v in vector[idx:idx+2] + [inserted_elements[int(idx/2)]]]
        
        

        输出将是

        [1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]
        

        【讨论】:

          【解决方案4】:

          这是一种有点晦涩难懂的方法 - 但它比其他任何方法都快(到目前为止):

          list(itertools.chain(*zip(*[iter(vector)]*2+[iter(inserted_elements)]))) 
          

          它使用“习惯用法”来获取大小为 n 组的项目,[iter(alist)]*n 和 itertools.chain 作为扁平化嵌套列表的一种方式。

          使用了np.insert 的已删除答案。为此,我相信insert 使用掩码,如下所示:

          def foo(vector, inserted_elements):
              res = np.zeros(len(vector)+len(inserted_elements),int)  
              mask = res.astype(bool) 
              mask[2::3]=True 
              res[mask]=inserted_elements 
              res[~mask]=vector    
              return res
          

          np.append 答案的一个变体是:

          np.column_stack((np.reshape(vector,(-1,2)), inserted_elements)).ravel()
          

          我一般不喜欢np.append,因为它经常被误用,尤其是在循环中。为此没关系,但我认为column_stack 更干净。

          ===

          In [254]: list(zip(*[iter(vector)]*2+[iter(inserted_elements)]))                                         
          Out[254]: [(1, 2, 2), (3, 4, 2), (5, 6, 2), (7, 8, 2), (9, 10, 2)]
          

          【讨论】:

          • foo 是我实现的,只是看到你已经这样做了哈哈。
          【解决方案5】:

          我认为对于任何可能大小的数组都没有简单的 NumPy 方法来执行此操作,但这里有一种使用迭代器和列表理解的 python 方法:

          it1, it2 = map(iter, (vector, inserted_elements))
          n = sum(map(len, (vector, inserted_elements)))
          
          [next(it2) if i % 3 == 0 else next(it1) for i in range(1, n+1)]
          # [1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]
          

          输出中的每个 3rd 元素将来自 it2,inserted_elements 的迭代器。其余来自it1,对应vector。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-03-20
            • 2021-12-22
            • 1970-01-01
            • 2016-09-08
            • 1970-01-01
            • 2016-04-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多