【问题标题】:Interleave 4 lists of same length python [duplicate]交错4个相同长度的python列表[重复]
【发布时间】:2018-11-21 08:31:09
【问题描述】:

我想在 python 中交错 4 个相同长度的列表。

我搜索了这个站点,只看到如何在 python 中交错 2: Interleaving two lists in Python

可以为 4 个列表提供建议吗?

我有这样的列表

l1 = ["a","b","c","d"]
l2 = [1,2,3,4]
l3 = ["w","x","y","z"]
l4 = [5,6,7,8]

我想要这样的列表

l5 = ["a",1,"w",5,"b",2,"x",6,"c",3,"y",7,"d",4,"z",8]

【问题讨论】:

    标签: python arrays python-3.x


    【解决方案1】:

    itertools.chainzip

    from itertools import chain
    l1 = ["a", "b", "c", "d"] l2 = [1, 2, 3, 4] l3 = ["w", "x", "y", "z"] l4 = [5, 6, 7, 8]
    print(list(chain(*zip(l1, l2, l3, l4))))

    或者正如@PatrickHaugh 建议的那样使用chain.from_iterable

    list(<b>chain.from_iterable(zip</b>(l1, l2, l3, l4)))

    【讨论】:

    • 我可能会使用chain.from_iterable
    • @PatrickHaugh 是的,我添加到我的答案中。谢谢你的意见。
    【解决方案2】:

    如果列表长度相同,zip() 可用于交错四个列表,就像在您链接的问题中用于交错两个列表一样:

    >>> l1 = ["a", "b", "c", "d"]
    >>> l2 = [1, 2, 3, 4]
    >>> l3 = ["w", "x", "y", "z"]
    >>> l4 = [5, 6, 7, 8]
    >>> l5 = [x for y in zip(l1, l2, l3, l4) for x in y]
    >>> l5
    ['a', 1, 'w', 5, 'b', 2, 'x', 6, 'c', 3, 'y', 7, 'd', 4, 'z', 8]
    

    【讨论】:

      【解决方案3】:

      使用zipreduce

      import functools, operator
      >>> functools.reduce(operator.add, zip(l1,l2,l3,l4))
      ('a', 1, 'w', 5, 'b', 2, 'x', 6, 'c', 3, 'y', 7, 'd', 4, 'z', 8)
      

      【讨论】:

      • 有没有理由使用functools.reduce(operator.add, x) 而不是sum(x)
      • @Daerdemandt 不,它们同样糟糕。
      • 是的,因为sum(zip(l1,l2,l3,l4)) 不起作用:TypeError: unsupported operand type(s) for +: 'int' and 'tuple'
      【解决方案4】:

      来自 itertools 食谱

      itertool recipes 提出了一个名为 roundrobin 的解决方案,它允许使用不同长度的列表。

      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))
      
      print(*roundrobin(*lists)) # a 1 w 5 b 2 x 6 c 3 y 7 d 4 z 8
      

      带切片

      或者,这里有一个完全依赖切片的解决方案,但要求所有列表的长度相同。

      l1 = ["a","b","c","d"]
      l2 = [1,2,3,4]
      l3 = ["w","x","y","z"]
      l4 = [5,6,7,8]
      
      lists = [l1, l2, l3, l4]
      
      lst = [None for _ in range(sum(len(l) for l in lists))]
      
      for i, l in enumerate(lists):
          lst[i:len(lists)*len(l):len(lists)] = l
      
      print(lst) # ['a', 1, 'w', 5, 'b', 2, 'x', 6, 'c', 3, 'y', 7, 'd', 4, 'z', 8]
      

      【讨论】:

        【解决方案5】:

        另一种方法是使用zipnp.concatenate

        import numpy as np
        l5 = np.concatenate(list(zip(l1, l2, l3, l4)))
        print(l5)
        

        结果:

        ['a' '1' 'w' '5' 'b' '2' 'x' '6' 'c' '3' 'y' '7' 'd' '4' 'z' '8']
        

        注意l5numpy.ndarray 类型,您可以使用list(l5)l5.tolist() 将其转换为list

        【讨论】:

          【解决方案6】:

          为了额外的多样性(或者如果你需要用 Pandas 来做这件事)

          import pandas as pd
          l1 = ["a","b","c","d"]
          l2 = [1,2,3,4]
          l3 = ["w","x","y","z"]
          l4 = [5,6,7,8]
          
          df = pd.DataFrame([l1 ,l2, l3, l4])
          result = list(df.values.flatten('A'))
          

          ['a', 1, 'w', 5, 'b', 2, 'x', 6, 'c', 3, 'y', 7, 'd', 4, 'z', 8]

          【讨论】:

            【解决方案7】:

            只是为了多样性,numpy.dstack 然后flatten 可以做同样的伎俩。

            >>> import numpy as np
            >>> l1 = ["a","b","c","d"]
            >>> l2 = [1,2,3,4]
            >>> l3 = ["w","x","y","z"]
            >>> l4 = [5,6,7,8]
            >>> np.dstack((np.array(l1),np.array(l2),np.array(l3),np.array(l4))).flatten()                                                                                                       
            array(['a', '1', 'w', '5', 'b', '2', 'x', '6', 'c', '3', 'y', '7', 'd',                                                                                                              
                   '4', 'z', '8'],                                                                                                                                                               
                  dtype='|S21') 
            

            顺便说一句,您实际上不需要制作数组,短版也可以使用

            >>> np.dstack((l1,l2,l3,l4)).flatten()                                                                                                       
            array(['a', '1', 'w', '5', 'b', '2', 'x', '6', 'c', '3', 'y', '7', 'd',                                                                                                              
                   '4', 'z', '8'],                                                                                                                                                               
                  dtype='|S21')   
            

            【讨论】:

              猜你喜欢
              • 2011-12-18
              • 2013-11-21
              • 1970-01-01
              • 1970-01-01
              • 2017-12-03
              • 2012-12-23
              • 1970-01-01
              • 2013-01-05
              • 2012-06-22
              相关资源
              最近更新 更多