[英]Array Rotation function changing Original Array
該代碼應該制作原始數組的副本並旋轉它(將列轉換為行),同時保持原始數組相同,但原始數組會無緣無故地更改。
這很可能是一個深拷貝問題,但我嘗試使用copy.copy()
並沒有奏效
代碼:
l = [[1,2,3],[4,5,6],[7,8,9]]
def rotate(funcl):
funcl = funcl[::-1]
for s1 in range(0, len(funcl)):
for s2 in range(s1, len(funcl)):
funcl[s1][s2], funcl[s2][s1] = funcl[s2][s1], funcl[s1][s2]
return funcl
print("Original Array:\n", l)
nextl = rotate(l)
print("Original Array after Function:\n", l)
print("New Rotated Array:\n", nextl)
Output:
Original Array:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Original Array after Function:
[[9, 6, 3], [8, 5, 2], [7, 4, 1]]
New Rotated Array:
[[7, 4, 1], [8, 5, 2], [9, 6, 3]]
如您所見,function 工作正常,但更改了原始數組
一種方法是在將其傳遞給 function 之前使用 copy.deepcopy() 進行深度復制,因此列表的每個級別和嵌套的子級別都是重復的:
import copy
l = [[1,2,3],[4,5,6],[7,8,9]]
def rotate(funcl):
funcl = funcl[::-1]
for s1 in range(0, len(funcl)):
for s2 in range(s1, len(funcl)):
funcl[s1][s2], funcl[s2][s1] = funcl[s2][s1], funcl[s1][s2]
return funcl
print("Original Array:\n", l)
nextl = rotate(copy.deepcopy(l))
print("Original Array after Function:\n", l)
print("New Rotated Array:\n", nextl)
output 是:
Original Array:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Original Array after Function:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
New Rotated Array:
[[7, 4, 1], [8, 5, 2], [9, 6, 3]]
這是一個有效的版本(加上打印這些列表的更好方法):
def printlst(arr):
for row in arr:
print(*row)
def rotate(funcl):
newl = [row.copy() for row in funcl]
newl = newl[::-1]
for s1 in range(0, len(newl)):
for s2 in range(s1, len(newl)):
newl[s1][s2], newl[s2][s1] = newl[s2][s1], newl[s1][s2]
return newl
l = [[1,2,3],[4,5,6],[7,8,9]]
print("Original Array:")
printlst(l)
nextl = rotate(l)
print("Original Array after Function:")
printlst(l)
print("New Rotated Array:")
printlst(nextl)
生成的 output:
Original Array:
1 2 3
4 5 6
7 8 9
Original Array after Function:
1 2 3
4 5 6
7 8 9
New Rotated Array:
7 4 1
8 5 2
9 6 3
另一種方法:
def rotate(funcl):
return [[funcl[j][i] for j in range(len(funcl))[::-1]] for i in range(len(funcl))]
deepcopy
是出了名的慢,如果可以的話應該避免。
zip()
經常用於轉置 python 中的列表。 這里唯一的皺紋是你想扭轉它們。 您可以為此使用reversed()
並獲得非常簡潔:
l = [[1,2,3],[4,5,6],[7,8,9]]
def rotate(funcl):
return list(zip(*reversed(funcl)))
print("Original Array:\n", l)
nextl = rotate(l)
print("Original Array after Function:\n", l)
print("New Rotated Array:\n", nextl)
哪個打印:
Original Array:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Original Array after Function:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
New Rotated Array:
[(7, 4, 1), (8, 5, 2), (9, 6, 3)]
如果維護內部列表而不是元組很重要,您可以添加 map 進行混合:
l = [[1,2,3],[4,5,6],[7,8,9]]
def rotate(funcl):
return list(map(list, zip(*reversed(funcl))))
# or return [list(t) for t in zip(*reversed(funcl))]
rotate(l)
# [[7, 4, 1], [8, 5, 2], [9, 6, 3]]
這確實是一個深拷貝問題: funcl = funcl[::-1]
只做淺拷貝。
無論如何,Pythonic 方法是直接使用雙列表理解構建轉置數組,避免復制后跟旋轉:
def rotate(funcl):
return [[funcl[j][i] for j in range(len(funcl))] for i in range(len(funcl))]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.