我想根据它们的索引模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 % ...
位,但它应该可以正常工作,对吗?)
是否有预先存在的功能可以做到这一点?
答案 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_arr
和arr
视为两个&#34;粘滞便笺&#34;附加到相同的底层列表对象,它将相应地更改。
如果您使用list()
内置
arr
arrtmp = list(arr)
您的方法适用于此特定情况。