即使列表未传递给函数,函数也会更改列表中的值
Functions change values in list even though list is not passed to functions
我正在尝试实施 I.A。类似广度优先搜索的算法来解决 Water Jugs 问题,但我遇到了这个问题:
每次我向数组中添加一个新元素时,它都会将数组中的所有元素更改为类似它。
换句话说...
"frontier" 数组在每次 "jug" 函数调用之间更改其中的所有元素。
有人可以分享一些关于这段代码的见解吗?
(我比较担心实现逻辑,所以没有优化)
代码:
J1SIZE = 3
J2SIZE = 4
frontier = []
explored = []
def IsEmpty(array):
result = False
if len(array) == 0:
result = True
return result
#Fill up a jug
def fillJug(tempNode, jug):
copyNode = tempNode
copyNode = copyNode
if jug == 1:
copyNode[0] = J1SIZE
elif jug == 2:
copyNode[1] = J2SIZE
print(copyNode)
return copyNode
#Empty a jug
def emptyJug(tempNode, jug):
copyNode = tempNode
if jug == 1:
copyNode[0] = 0
elif jug == 2:
copyNode[1] = 0
print(copyNode)
return copyNode
#Pass the content of a jug to another
def passJug(tempNode, jug):
copyNode = tempNode
if jug == 1:
copyNode[1] = copyNode.j1
copyNode[0] = 0
if copyNode[1] > J2SIZE:
copyNode[1] = J2SIZE
elif jug == 2:
copyNode[0] = copyNode[1]
copyNode[1] = 0
if copyNode[0] > J1SIZE:
copyNode[0] = J1SIZE
print(copyNode)
return copyNode
#Check if solution was found
def goalTest(goalNode,currentNode):
result = False
if goalNode == currentNode:
result = True
return result
def BFS(start,end,frontier,explored):
start_node = start
frontier = [start_node] + frontier
if goalTest(end,(frontier[0])):
print('Solution:', frontier[0])
exit()
#Loop start
while IsEmpty(frontier) == False:
tempNode = frontier.pop(0)
#Generate nodes (states)
if tempNode[0] < J1SIZE:
newNode = fillJug(tempNode, 1)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier1: ', frontier)
if tempNode[1] < J2SIZE:
newNode = fillJug(tempNode, 2)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier2: ', frontier)
if tempNode[0] == J1SIZE:
newNode = emptyJug(tempNode, 1)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier3: ', frontier)
if tempNode[1] == J2SIZE:
newNode = emptyJug(tempNode, 2)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier4: ', frontier)
if (tempNode[0] > 0) and (tempNode[1] < J2SIZE):
newNode = passJug(tempNode, 1)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier5: ', frontier)
if (tempNode[1] > 0) and (tempNode[0] < J1SIZE):
new_node = passJug(tempNode, 2)
if new_node not in explored:
frontier = [new_node] + frontier
print('Frontier6: ', frontier)
print('Frontier: ', frontier)
print('Explored: ', explored)
for node in frontier:
if goalTest(end, node):
print('Solution:', frontier[0])
exit()
if node not in explored:
explored = [node] + explored
BFS([0,0],[0,2],frontier,explored)
固定码:
我制作了一个更小的代码示例来重现您的错误:
J1SIZE = 3
J2SIZE = 4
def fillJug(tempNode, jug):
copyNode = tempNode
copyNode = copyNode
if jug == 1:
copyNode[0] = J1SIZE
elif jug == 2:
copyNode[1] = J2SIZE
return copyNode
frontier = [[0, 0]]
tempNode = frontier.pop(0)
newNode = fillJug(tempNode, 1)
frontier = [newNode] + frontier # (1)
newNode = fillJug(tempNode, 2) # (2)
frontier = [newNode] + frontier
问题在于,在我标记为 (1)
的行中,您正在设置 newNode
,它指的是与 tempNode
相同的对象作为 frontier
。然后,在我标记为 (2)
的行中,您正在更改 tempNode
-- 在 fillJug
内。因此 frontier
中的值发生变化。具体来说,您让 copyNode
引用与 tempNode
相同的对象,然后您正在更改 copyNode
(和 tempNode
)引用的数据。
您应该将 copyNode
重新定义为
copyNode = tempNode[:]
这将导致 copyNode
和 tempNode
引用内存中的不同对象(具有相同的值)。 (另一种选择是在导入 copy
后将 copyNode
设置为 copy.copy(tempNode)
。)
所以新的 fillJug
将是
def fillJug(tempNode, jug):
copyNode = tempNode[:]
if jug == 1:
copyNode[0] = J1SIZE
elif jug == 2:
copyNode[1] = J2SIZE
return copyNode
同样的修复适用于其他 Jug
函数。
我正在尝试实施 I.A。类似广度优先搜索的算法来解决 Water Jugs 问题,但我遇到了这个问题:
每次我向数组中添加一个新元素时,它都会将数组中的所有元素更改为类似它。
换句话说...
"frontier" 数组在每次 "jug" 函数调用之间更改其中的所有元素。
有人可以分享一些关于这段代码的见解吗?
(我比较担心实现逻辑,所以没有优化)
代码:
J1SIZE = 3
J2SIZE = 4
frontier = []
explored = []
def IsEmpty(array):
result = False
if len(array) == 0:
result = True
return result
#Fill up a jug
def fillJug(tempNode, jug):
copyNode = tempNode
copyNode = copyNode
if jug == 1:
copyNode[0] = J1SIZE
elif jug == 2:
copyNode[1] = J2SIZE
print(copyNode)
return copyNode
#Empty a jug
def emptyJug(tempNode, jug):
copyNode = tempNode
if jug == 1:
copyNode[0] = 0
elif jug == 2:
copyNode[1] = 0
print(copyNode)
return copyNode
#Pass the content of a jug to another
def passJug(tempNode, jug):
copyNode = tempNode
if jug == 1:
copyNode[1] = copyNode.j1
copyNode[0] = 0
if copyNode[1] > J2SIZE:
copyNode[1] = J2SIZE
elif jug == 2:
copyNode[0] = copyNode[1]
copyNode[1] = 0
if copyNode[0] > J1SIZE:
copyNode[0] = J1SIZE
print(copyNode)
return copyNode
#Check if solution was found
def goalTest(goalNode,currentNode):
result = False
if goalNode == currentNode:
result = True
return result
def BFS(start,end,frontier,explored):
start_node = start
frontier = [start_node] + frontier
if goalTest(end,(frontier[0])):
print('Solution:', frontier[0])
exit()
#Loop start
while IsEmpty(frontier) == False:
tempNode = frontier.pop(0)
#Generate nodes (states)
if tempNode[0] < J1SIZE:
newNode = fillJug(tempNode, 1)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier1: ', frontier)
if tempNode[1] < J2SIZE:
newNode = fillJug(tempNode, 2)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier2: ', frontier)
if tempNode[0] == J1SIZE:
newNode = emptyJug(tempNode, 1)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier3: ', frontier)
if tempNode[1] == J2SIZE:
newNode = emptyJug(tempNode, 2)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier4: ', frontier)
if (tempNode[0] > 0) and (tempNode[1] < J2SIZE):
newNode = passJug(tempNode, 1)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier5: ', frontier)
if (tempNode[1] > 0) and (tempNode[0] < J1SIZE):
new_node = passJug(tempNode, 2)
if new_node not in explored:
frontier = [new_node] + frontier
print('Frontier6: ', frontier)
print('Frontier: ', frontier)
print('Explored: ', explored)
for node in frontier:
if goalTest(end, node):
print('Solution:', frontier[0])
exit()
if node not in explored:
explored = [node] + explored
BFS([0,0],[0,2],frontier,explored)
固定码:
我制作了一个更小的代码示例来重现您的错误:
J1SIZE = 3
J2SIZE = 4
def fillJug(tempNode, jug):
copyNode = tempNode
copyNode = copyNode
if jug == 1:
copyNode[0] = J1SIZE
elif jug == 2:
copyNode[1] = J2SIZE
return copyNode
frontier = [[0, 0]]
tempNode = frontier.pop(0)
newNode = fillJug(tempNode, 1)
frontier = [newNode] + frontier # (1)
newNode = fillJug(tempNode, 2) # (2)
frontier = [newNode] + frontier
问题在于,在我标记为 (1)
的行中,您正在设置 newNode
,它指的是与 tempNode
相同的对象作为 frontier
。然后,在我标记为 (2)
的行中,您正在更改 tempNode
-- 在 fillJug
内。因此 frontier
中的值发生变化。具体来说,您让 copyNode
引用与 tempNode
相同的对象,然后您正在更改 copyNode
(和 tempNode
)引用的数据。
您应该将 copyNode
重新定义为
copyNode = tempNode[:]
这将导致 copyNode
和 tempNode
引用内存中的不同对象(具有相同的值)。 (另一种选择是在导入 copy
后将 copyNode
设置为 copy.copy(tempNode)
。)
所以新的 fillJug
将是
def fillJug(tempNode, jug):
copyNode = tempNode[:]
if jug == 1:
copyNode[0] = J1SIZE
elif jug == 2:
copyNode[1] = J2SIZE
return copyNode
同样的修复适用于其他 Jug
函数。