我正在尝试在Python中对List中的数字进行循环旋转。
例如,
给出一个由N个整数组成的数组A。数组的旋转意味着每个元素右移一个索引,并将数组的最后一个元素移动到第一位。例如,数组 A = [3, 8, 9, 7, 6] 的旋转为 [6, 3, 8, 9, 7](元素右移一个索引,6 移至第一位)。
目标是将数组 A 旋转 K 次;即A的每个元素都会右移K次。
例如,给定
A = [3, 8, 9, 7, 6]
K = 3
该函数应返回 [9, 7, 6, 3, 8]。进行了三轮旋转:
[3, 8, 9, 7, 6] -> [6, 3, 8, 9, 7]
[6, 3, 8, 9, 7] -> [7, 6, 3, 8, 9]
[7, 6, 3, 8, 9] -> [9, 7, 6, 3, 8]
我编写了一个应该执行上述任务的函数。这是我的代码:
def sol(A, K):
for i in range(len(A)):
if (i+K) < len(A):
A[i+K] = A[i]
else:
A[i+K - len(A)] = A[i]
return A
A = [3, 8, 9, 7, 6]
K = 3
# call the function
sol(A,K)
[9, 3, 8, 3, 8]
我得到的是 [9, 3, 8, 3, 8] 而不是 [9, 7, 6, 3, 8]。
任何人都可以帮我完成上面的代码吗?
谢谢。
让我们看看如果
K
= 1,在第一次迭代时会发生什么:
def sol(A, K):
for i in range(len(A)): # i = 0
if (i+K) < len(A): # i + 1 < 5
A[i+K] = A[i] # A[1] = A[0]
else:
A[i+K - len(A)] = A[i]
# A is now equal to [3, 3, 9, 7, 6] - the element at A[1] got overwritten
return A
问题是您没有任何地方可以存储要覆盖的元素,并且您在旋转它们之前覆盖它们。理想的解决方案是“创建一个新列表”,用前一个列表中的旋转元素填充它,然后返回该列表。如果需要修改旧列表,可以从新列表中复制元素:
def sol(A, K):
ret = []
for i in range(len(A)):
if (i + K) < len(A):
ret.append(A[i + K])
else:
ret.append(A[i + K - len(A)])
return ret
或者,更简洁(可能是你的老师希望你如何解决它),使用取模运算符
:
def sol(A, K):
return [
A[(i + K) % len(A)]
for i in range(len(A))
]
可以说,最Pythonic的解决方案是连接两个列表切片,将索引
K
之后的列表部分移动到前面:
def sol(A, K):
return A[K % len(A):] + A[:K % len(A)]