簡體   English   中英

陣列旋轉 function 改變原始陣列

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM