如何用一个class来存储在不同函数中更新的变量,然后在不同函数中调用这些更新的变量?

How to use a class to store variables that are updated in different functions, and then call these updated variables in different functions?

我正在解决一个涉及之字形遍历一个n x m matrix的问题,其中n and m可以是相同的数字或不同的数字,即我们将有一个 正方形或矩形矩阵 .

为了解决这个问题,我有一个 main 方法,它会遍历矩阵;在这个主要方法中,我在 moveDiagonallyUpwardsmoveDiagonallyDownwards 方法上创建并调用 以之字形方式移动。

我遇到的问题是,当我将 rowcol 作为参数从 main 方法传递给这两个其他方法时,在这些方法中我更新了行和列,例如+=1 或 -= 1。 当我 return 到 main 方法时,这些更改不会反映在 main 方法中。我明白为什么会这样。

所以我的挑战是,如何将更新后的 rowcol 传递回 main 方法?我想到了使用 global class 来实现上述目标。 我的想法是创建一个单独的 class 来保存这些变量,如下所示,但是我在 main 方法 中调用和使用这些 global row and col 时遇到问题。

任何想法如何调整 main 方法 中的 row and col 以实现上述目标?谢谢!

array = [
    [1, 3, 4, 10],
    [2, 5, 9, 11],
    [6, 8, 12, 15],
    [7, 13, 14, 16]
  ]

class matrixMovement: 
    def __init__(self,row=0,col=0,output=[]): 
        self.row = row
        self.col = col
        self.output = output
#Main Method
def zigzagTraverse(array):
    output.append(array[row][col])
    while array.row<= len(array)-1 or array.col<= len(array[0])-1: 
        if array.row< len(array)-1: 
            array.row += 1
            output.append(array[row][col])
            diagonalUp(row,col,array,output)
        if col < len(array[0])-1: 
            col += 1
            output.append(array[row][col])
            diagonalDown(row,col,array,output)
    return output
            
def diagonalUp(row,col,array,output): 
    while row > 0 and col< len(array[0])-1: 
        row -= 1
        col += 1
        output.append(array[row][col])
    return matrixMovemenet(row,col,output)
    
def diagonalDown(row,col,array,output): 
    while row<len(array)-1 and col > 0: 
        col-= 1
        row += 1
        output.append(array[row][col])
    return matrixMovemenet(row,col,output)

你有一些问题。一种是本地范围。另一个是使用 return 语句但不对返回的对象执行任何操作。

有几种方法可以解决这个问题。一种是忽略局部变量,只从 matrixMovement 创建一个对象并利用它可变的事实。

class MatrixMovement: 
    def __init__(self, row=0, col=0, output=None):
        # I modified this to avoid the mutable default
        if output is None:
            output = []
        self.row = row
        self.col = col
        self.output = output


# Main Method
def zigzag_traverse(array):
    # this is the object we will be mutating
    obj = MatrixMovement()
    obj.output.append(array[obj.row][obj.col])
    while obj.row <= len(array) - 1 or obj.col <= len(array[0]) - 1: 
        if obj.row < len(array) - 1: 
            obj.row += 1
            obj.output.append(array[obj.row][obj.col])
            diagonal_up(obj, array)
        if obj.col < len(array[0]) - 1: 
            obj.col += 1
            obj.output.append(array[obj.row][obj.col])
            diagonal_down(obj, array)
        # without this condition the loop will never break
        if obj.row == len(array) - 1 and obj.col == len(array[0]) - 1:
            break
    return obj.output


def diagonal_up(obj, array):
    # since we are passing in a mutable object
    # anything attribute we change on it
    # will be reflected on the object from the call site
    while obj.row > 0 and obj.col < len(array[0]) - 1: 
        obj.row -= 1
        obj.col += 1
        obj.output.append(array[obj.row][obj.col])


def diagonal_down(obj, array):
    # the same rules as diagonal_up
    while obj.row < len(array) - 1 and obj.col > 0: 
        obj.col -= 1
        obj.row += 1
        obj.output.append(array[obj.row][obj.col])

我选择使用文档、边界检查以及解决我在您的遍历中发现的一些错误来编写此代码。

说明写在评​​论里。有什么不懂的欢迎提问

from typing import TypeVar, Sequence, TypeAlias

from dataclasses import dataclass

_T = TypeVar("_T")

MatrixType = Sequence[Sequence[_T]]

@dataclass
class Point:
    row: int
    col: int

def zigzag_traverse(matrix: MatrixType[_T]) -> list[_T]:
    output: list[_T] = []

    row_length = len(matrix[0])
    if any(len(row) != row_length for row in matrix):
        raise ValueError("Matrix is not rectangular.")
    
    # Initialize.
    boundry = Point(len(matrix) - 1, row_length - 1)
    
    if boundry.row < 0 or boundry.col < 0:
        return output  # Matrix is empty.

    pointer = Point(0, 0)


    # Start traversing.

    output.append(matrix[pointer.row][pointer.col])
    
    
    while pointer != boundry:

        # Go right until edge, then start moving down.
        if pointer.col < boundry.col:
            pointer.col += 1
        else:
            pointer.row += 1

        output.extend(_diagonal_left_down(pointer, matrix))

        # We reached the boundry, stop traversing.
        if pointer == boundry:
            break

        # Go down until edge, then start moving right.
        if pointer.row < boundry.row:
            pointer.row += 1
        else:
            pointer.col += 1

        output.extend(_diagonal_right_up(pointer, matrix))
    
    return output

def _diagonal_left_down(pointer: Point, matrix: MatrixType[_T]) -> list[_T]:
    """Traverse left-down diagonal.
    
    Args:
        pointer: The current position. Will be modified.
        matrix: The matrix to move over.
    
    Returns:
        The list of elements traversed.
    """
    row, col = pointer.row, pointer.col
    output = []

    while row < len(matrix) - 1 and col > 0:
        output.append(matrix[row][col])
        row += 1
        col -= 1
    
    # Reached the edge
    output.append(matrix[row][col])
    pointer.row, pointer.col = row, col

    return output

def _diagonal_right_up(pointer: Point, matrix: MatrixType[_T]) -> list[_T]:
    """Traverse right-up diagonal.
    
    Args:
        pointer: The current position. Will be modified.
        matrix: The matrix to move over.
    
    Returns:
        The list of elements traversed.
    """
    row, col = pointer.row, pointer.col
    output = []

    while row > 0 and col < len(matrix[0]) - 1:
        output.append(matrix[row][col])
        row -= 1
        col += 1
    
    # Reached the edge
    output.append(matrix[row][col])
    pointer.row, pointer.col = row, col

    return output