如何根据索引模3进行列表元素的置换?

时间:2016-07-01 09:18:36

标签: python sorting permutation

我想根据它们的索引模3来置换列表的元素,例如列表:

[0,1,2,3,4,5,6,7,8]

应该重新订购:

[0,3,6,1,4,7,2,5,8]

一般来说:

[A0, A1, A2, A3, A4, A5, A6, A7, A8]

应该成为:

[A0, A3, A6, A1, A4, A7, A2, A5, A8]

我尝试使用以下代码:

def arr_sort(arr, algo):
    arrtmp = arr

    arrlen = len(arr)

    if algo == 1:
        return arr

    if algo == 2:
        count = 0
        while count < (arrlen - 1):
            for index, val in enumerate(arr):
                if index % 3 == 0:
                    arrtmp[count] = val
                    count += 1
            for index, val in enumerate(arr):
                if index % 3 == 1:
                    arrtmp[count] = val
                    count += 1
            for index, val in enumerate(arr):
                if index % 3 == 2:
                    arrtmp[count] = val
                    count += 1

    return arrtmp

它无法正常工作,因为arr在整个循环过程中发生了变化,我无法理解为什么。 (我也知道我也可以在for循环中执行&#34; f index % ...位,但它应该可以正常工作,对吗?)

是否有预先存在的功能可以做到这一点?

4 个答案:

答案 0 :(得分:5)

您正在重新排序3

的模数
l = [0,1,2,3,4,5,6,7,8]

l_sorted = sorted(l, key=lambda x: x%3)
print(l_sorted)
# [0, 3, 6, 1, 4, 7, 2, 5, 8]

如果您要对索引进行重新排序而不是对值进行重新排序,那么需要enumerate更详细的内容就可以做到:

l_sorted = [x[1] for x in sorted(enumerate(l), key=lambda x: x[0]%3)]
print(l_sorted)
# [0, 3, 6, 1, 4, 7, 2, 5, 8]

答案 1 :(得分:3)

另一个基于索引的是

l_sorted = sum([l[x::3] for x in range(3)],[])

答案 2 :(得分:2)

a = [0,1,2,3,4,5,6,7,8]

a[::3]将为您提供第三个元素:[0, 3, 6]

a[n::3]会从n开始为您提供每个第三个元素,因此a[1::3]变为[1, 4, 7]a[2::3]变为[2, 5, 8]

将这些列表与+连接起来:a[0::3] + a[1::3] + a[2::3]按指定评估为[0, 3, 6, 1, 4, 7, 2, 5, 8]

答案 3 :(得分:1)

这是通过分组某个步骤将列表链接在一起的通用解决方案。 itertools.chain.from_iterable用于将每个步骤中的结果组链接在一起。

from itertools import chain

def step_chain(l, step_len):
    return chain.from_iterable(l[s::step_len] for s in range(step_len))

<强>演示

>>> l = [0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> list(step_chain(l, 2))
[0, 2, 4, 6, 8, 1, 3, 5, 7]
>>> list(step_chain(l, 3))
[0, 3, 6, 1, 4, 7, 2, 5, 8]

如果步长不适合列表,则附加元素放在新列表的末尾,如果步长大于列表,则显然返回原始列表。

>>> step_chain(l, 7)
[0, 7, 1, 8, 2, 3, 4, 5, 6]
>>> step_chain(l, 100)
[0, 1, 2, 3, 4, 5, 6, 7, 8]

为什么您的尝试不起作用

当您设置temp_arr = arr时,temp_arr只是与arr相同的基础(可变)列表中的引用。因此你正在修改它。您可以将temp_arrarr视为两个&#34;粘滞便笺&#34;附加到相同的底层列表对象,它将相应地更改。

如果您使用list()内置

复制原始列表arr
arrtmp = list(arr)

您的方法适用于此特定情况。