【问题标题】:How to Reorder Python List For Every N Item如何为每 N 个项目重新排序 Python 列表
【发布时间】:2016-11-10 10:09:38
【问题描述】:

我有一个像 ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', ' k']

如何根据每 n 项(例如每 4 项)重新排序,使其具有第 1 项,然后是第 5 项,然后是第 9 项,然后是第 2 项,然后是第 6 项,然后是第 10 项项,然后是第 3 项、第 7 项和第 11 项,然后是第 4 项、第 8 项和第 12 项。 (是的,我很抱歉在写出来时开始以 1 而不是 0 计数......)

['a', 'e', 'i', 'b', 'f', 'j', 'c', 'g', 'k']

【问题讨论】:

    标签: python list list-comprehension


    【解决方案1】:

    我怀疑这是最高效或最优雅的解决方案,但它确实有效:

    >>>lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
    >>>lst[::4] + lst[1::4] + lst[2::4] + lst[3::4]
    ['a', 'e', 'i', 'b', 'f', 'j', 'c', 'g', 'k', 'd', 'h']
    

    【讨论】:

    • 如果你有一千个加数?
    【解决方案2】:

    更新

    Mark Tolonen 是正确的,原始解决方案仅在少数情况下有效。这是一个更正的版本:

    >>> flatten = lambda x: reduce(lambda a,b: a+b, x)
    >>> everyN = lambda N,l: flatten([l[s:][::N] for s in range(N)])
    

    注意:flatten可以在many ways中实现(包括itertools.chain.from_iterable)。

    示例用法:

    >>> everyN(4, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'])
    ['a', 'e', 'i', 'b', 'f', 'j', 'c', 'g', 'k', 'd', 'h']
    
    >>> everyN(4, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'])
    ['a', 'e', 'i', 'b', 'f', 'j', 'c', 'g', 'k', 'd', 'h', 'l']
    
    >>> everyN(2, ['a','b','c'])
    ['a', 'c', 'b']
    

    原解决方案

    >>> import itertools
    >>> l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
    >>> step = 4
    >>> list(itertools.islice(l*step, None, None, step))
    ['a', 'e', 'i', 'b', 'f', 'j', 'c', 'g', 'k', 'd', 'h']
    

    请注意,list() 调用通常不是必需的,因为大多数采用列表的东西也会采用迭代器对象。但是显示结果很方便。

    【讨论】:

    • 这仅适用于列表小于 4 的倍数。添加另一个项目或更改步骤,它会中断。
    • @MarkTolonen 是真的。我更新了一个更好的解决方案。
    【解决方案3】:

    你可以这样做:

        l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
        f = []
        n = 4
    
        for i in range(n):
            f.extend(l[i::n])
    

    【讨论】:

      【解决方案4】:

      这支持任意N步的任意长度列表:

      from itertools import islice
      
      def reorder(L,N):
          return [x for n in range(N) for x in islice(L,n,None,N)]
      
      L = list(range(16))
      for N in range(1,9):
          print(N,reorder(L,N))
      
      L = list('abcdefghijk')
      for N in range(1,9):
          print(N,reorder(L,N))
      

      输出:

      1 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
      2 [0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15]
      3 [0, 3, 6, 9, 12, 15, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14]
      4 [0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15]
      5 [0, 5, 10, 15, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14]
      6 [0, 6, 12, 1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 5, 11]
      7 [0, 7, 14, 1, 8, 15, 2, 9, 3, 10, 4, 11, 5, 12, 6, 13]
      8 [0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15]
      1 ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
      2 ['a', 'c', 'e', 'g', 'i', 'k', 'b', 'd', 'f', 'h', 'j']
      3 ['a', 'd', 'g', 'j', 'b', 'e', 'h', 'k', 'c', 'f', 'i']
      4 ['a', 'e', 'i', 'b', 'f', 'j', 'c', 'g', 'k', 'd', 'h']
      5 ['a', 'f', 'k', 'b', 'g', 'c', 'h', 'd', 'i', 'e', 'j']
      6 ['a', 'g', 'b', 'h', 'c', 'i', 'd', 'j', 'e', 'k', 'f']
      7 ['a', 'h', 'b', 'i', 'c', 'j', 'd', 'k', 'e', 'f', 'g']
      8 ['a', 'i', 'b', 'j', 'c', 'k', 'd', 'e', 'f', 'g', 'h']
      

      【讨论】:

        【解决方案5】:

        你可以用一个简单的单线做到这一点:

        lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
        every4 = [s for i in range(4) for s in lst[i::4]]
        

        这是对 James Moriarty 解决方案的简单重写。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-07-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-19
          相关资源
          最近更新 更多