如何为每N个项重新排序Python列表

时间:2016-07-07 22:53:29

标签: python list list-comprehension

我有一个列表,如['a','b','c','d','e','f','g','h','i','j',' K']

如何根据每n项(例如每4项)对其进行重新排序,使其具有第1项,然后是第5项,然后是第9项,然后是第2项,然后是第6项,然后是第10项item,然后是第3项,第7项和第11项,然后是第4项,第8项和第12项。 (是的,我很遗憾开始用1来代替0来写出来......)

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

5 个答案:

答案 0 :(得分:5)

<强>更新

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可以在MIME type中实施(包括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()调用通常不是必需的,因为大多数采用列表的东西也会使用迭代器对象。但是显示结果很方便。

答案 1 :(得分:2)

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

>>>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 :(得分:1)

你可以这样做:

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

答案 3 :(得分:1)

这支持任何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']

答案 4 :(得分:1)

你可以用一个简单的单行代码来完成:

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解决方案的简单改写。