我正在尝试按给定顺序创建两个子数组,在这种情况下,我有两个整数 a 和 ba
表示子数组范围的值,b
表示需要旋转多少次。
我像这样创建了子数组;
def reorder(a,b):
return [[i for i in range(0, a//2)]] + [[f for f in range(a//2, a)]]
假设a
是10,b
是1,输出是:
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
但是,如何将每个子阵列反转b
次呢?
我想要的输出;
[[4, 0, 1, 2, 3], [9, 5, 6, 7, 8]]
您可以通过切片来旋转内部列表:
def reorder(a,b):
slicingPosition = a/2 % b
return [y[-slicingPosition:] + y[:-slicingPosition] for y in [[i for i in range(0, a//2)]] + [[f for f in range(a//2, a)]]]
for x in range(1, 6):
print(x, '>>', reorder(10, x))
输出:
(1, '>>', [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])
(2, '>>', [[4, 0, 1, 2, 3], [9, 5, 6, 7, 8]])
(3, '>>', [[3, 4, 0, 1, 2], [8, 9, 5, 6, 7]])
(4, '>>', [[4, 0, 1, 2, 3], [9, 5, 6, 7, 8]])
(5, '>>', [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])
你可以弹出每个子数组的最后一个元素 b 次并将其插入开头:
def reorder(a,b):
suba = [i for i in range(0, a//2)]
subb = [f for f in range(a//2, a)]
for i in range(b):
suba = [suba.pop(-1)]+suba
subb = [subb.pop(-1)]+subb
return [suba,subb]
In[1]: reorder(10,1)
Out[1]: [[4, 0, 1, 2, 3], [9, 5, 6, 7, 8]]
您可以使用具有内置rotate()
函数的双端 que,
from collections import deque
def reorder(a,b):
my_arr = [[i for i in range(0, a//2)]] + [[f for f in range(a//2, a)]]
first_q = deque(my_arr[0])
second_q = deque(my_arr[1])
first_q.rotate(b)
second_q.rotate(b)
return [list(first_q), list(second_q)]
print(reorder(10, 1))
您也可以使用索引。这样:
def reorder(a, b):
tmp = [[i for i in range(0, a//2)]] + [[f for f in range(a//2, a)]]
tmp[0] = tmp[0][-b:] + tmp[0][:-b]
tmp[1] = tmp[1][-b:] + tmp[1][:-b]
return tmp
reorder(10, 1)
输出:
[[4, 0, 1, 2, 3], [9, 5, 6, 7, 8]]
<小时 />编辑
对于b
大于a/2
的边缘情况。这样使用模数:
def reorder(a, b):
sz = a//2
r = b%sz
tmp = [[i for i in range(0, sz)]] + [[f for f in range(sz, a)]]
tmp[0] = tmp[0][-r:] + tmp[0][:-r]
tmp[1] = tmp[1][-r:] + tmp[1][:-r]
return tmp
reorder(10, 7)
[[3, 4, 0, 1, 2], [8, 9, 5, 6, 7]]
这也可以在莫里斯·迈耶的答案中完成(迄今为止最好的(。
我也想出了这些解决方案。
具有 numpy 的滚动功能;
import numpy as np
def reorder(a, b):
return [list(np.roll(v,b)) for v in [list(range(a//2)),list(range(a-a//2,a))]]
In: reorder(10,9)
Out: [[1, 2, 3, 4, 0], [6, 7, 8, 9, 5]]
具有numpy滚动功能的解决方案也简单得多;
import numpy as np
def reorder(a, b):
return np.roll(np.arange(a).reshape(2, -1), b, 1).tolist()
In: reorder(10,9)
Out: [[1, 2, 3, 4, 0], [6, 7, 8, 9, 5]]
如果您不想使用包装并且您可以接受一点眼睛出血;
def reorder(a, b):
return [list(range(a//2))[-b%(a//2):] + list(range(a//2))[:-b%(a//2)], list(range(a//2, a))[-b%(a//2):] + list(range(a//2, a))[:-b%(a//2)]]
In: reorder(10,9)
Out: [[1, 2, 3, 4, 0], [6, 7, 8, 9, 5]]
如果适用,我建议使用 deque。 我希望它能更快
。import collections
def reorder(a,b):
tmp = [[i for i in range(0, a//2)]] + [[f for f in range(a//2, a)]]
for i in range(len(tmp)):
tmp[i] = collections.deque(tmp[i])
# rotates to right for positive numbers
tmp[i].rotate(b)
print d
>>> deque([3, 4, 5, 1, 2])