追加到递归函数内的列表会更改所有项目吗?河内塔

问题描述 投票:0回答:2

我正在尝试使用 numpy 制作一个矩阵列表来表示解决河内塔问题的最小移动次数。当我在每次移动后打印 m 时,我的解决方案有效,但是当我尝试将 m 附加到列表时,结果列表仅包含一遍又一遍重复的最终矩阵。这是我的代码:

def set_up(total,start):
    global moves

    moves = 0
    m = np.empty((3,total+1))
    for i in range(3):
        for j in range(total+1):
            m[i,j] = -1
    for i in range(total):
        m[start,i] = int(total-i-1)

    m_list = [m]
    return m,m_list

def move_disk(total,num,m,move_from,move_to,m_list):
    global moves
    temp =m[move_from,np.where(m[move_from]==-1)[0][0]-1]
    m[move_from,np.where(m[move_from]==-1)[0][0]-1]= -1
    m[move_to,np.where(m[move_to]==-1)[0][0]] = temp
    moves = moves + 1
    m_list.append(m)

def towers_algorithm(total,num,m,start,middle,final,m_list):

    if num == 0:
        return
    else:
        towers_algorithm(total,num-1,m,start,final,middle,m_list)
        move_disk(total,num,m,start,final,m_list)
        towers_algorithm(total,num-1,m,middle,start,final,m_list)

我尝试将列表作为参数传递并使 m_list 成为全局变量。两者给出了相同的结果。

python numpy recursion matrix append
2个回答
0
投票

您的

set_up
函数创建一个
m
矩阵,并且这是创建此类矩阵的唯一一次。其余代码会变异
m
并执行
m_list.append(m)
。但这会将相同的数组引用多次附加到
m_list
,因此
m_list
只会有重复项。请注意,只有一个
m
数组,因此您不能期望
m_list
以某种方式引用多个不同的数组。

要解决此问题,请确保每次追加到 m_list 时都创建一个新数组。您可以通过不同的方式实现这一点,例如:

m_list.append(m.copy())



0
投票
m

附加到

m_list
,其中
m
仅表示对您创建和分配的一个实例的引用。这意味着每当
m
的值发生变化时,无论您在何处使用引用,它也将指向同一个对象。
为了解决该问题,您必须在想要使用其当前值的某个点创建对象的副本。

m_list.append(m.copy())

这将创建一个具有相同值的新实例。

© www.soinside.com 2019 - 2024. All rights reserved.