Python:为什么一个函数能够在另一个函数中改变数组?我猜是';这是一个范围问题
我很困惑。我不明白如何通过在Python:为什么一个函数能够在另一个函数中改变数组?我猜是';这是一个范围问题,python,python-3.x,scope,Python,Python 3.x,Scope,我很困惑。我不明白如何通过在DFS中进行更改,在numIslands中更新访问的 我的理解是,访问过的,一旦传递到DFS,就像是原始的访问过的的副本 不是这样吗 class Solution: def DFS(self, grid, visited, i, j): if i < 0 or j < 0 or i >= len(grid) or j >= len(grid[0]) or visited[i][j] or grid[i][j] == '0
DFS
中进行更改,在numIslands
中更新访问的
我的理解是,访问过的
,一旦传递到DFS
,就像是原始的访问过的
的副本
不是这样吗
class Solution:
def DFS(self, grid, visited, i, j):
if i < 0 or j < 0 or i >= len(grid) or j >= len(grid[0]) or visited[i][j] or grid[i][j] == '0':
return
visited[i][j] = True
self.DFS(grid, visited, i+1, j)
self.DFS(grid, visited, i-1, j)
self.DFS(grid, visited, i, j+1)
self.DFS(grid, visited, i, j-1)
def numIslands(self, grid: List[List[str]]) -> int:
if not grid: return 0
visited = [[False for i in range(len(grid[0]))] for j in range(len(grid))]
count = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == '1' and visited[i][j] == False:
self.DFS(grid, visited, i, j) # TODO
count += 1
return count
类解决方案:
def DFS(自我、网格、访问、i、j):
如果i<0或j<0或i>=len(网格)或j>=len(网格[0]),或访问了[i][j]或网格[i][j]='0':
返回
访问[i][j]=正确
self.DFS(网格、访问、i+1、j)
自助式DFS(网格、访问、i-1、j)
self.DFS(网格、访问、i、j+1)
自助式DFS(网格、访问、i、j-1)
def numIslands(self,grid:List[List[str]])->int:
如果不是网格:返回0
visited=[[False for i in range(len(grid[0]))]for j in range(len(grid))]
计数=0
对于范围内的i(len(网格)):
对于范围内的j(len(网格[0]):
如果网格[i][j]='1'并且访问了[i][j]==False:
self.DFS(网格、访问、i、j)#待办事项
计数+=1
返回计数
我的理解是,访问,一旦进入DFS,就像一个原始访问的副本
事实并非如此。Python从不为您创建隐式副本。如果将对象传递给函数,则不会生成该对象的副本。您只需在函数范围内为与visted
关联的对象赋予另一个名称visted
要使DFS
在numIslands
中独立于访问的运行,您需要制作一份深度拷贝:
from copy import deepcopy
. . .
self.DFS(grid, deepcopy(visited), i, j)
尽管这通常不是一个好主意,因为deepcopy
是一个相当昂贵的函数,我认为您无论如何都不想在这里这么做。该算法要求DFS
mutatevisitored
。如果它没有返回值,DFS
将不会执行任何操作
我的理解是,访问,一旦进入DFS,就像一个原始访问的副本
事实并非如此。Python从不为您创建隐式副本。如果将对象传递给函数,则不会生成该对象的副本。您只需在函数范围内为与visted
关联的对象赋予另一个名称visted
要使DFS
在numIslands
中独立于访问的运行,您需要制作一份深度拷贝:
from copy import deepcopy
. . .
self.DFS(grid, deepcopy(visited), i, j)
尽管这通常不是一个好主意,因为deepcopy
是一个相当昂贵的函数,我认为您无论如何都不想在这里这么做。该算法要求DFS
mutatevisitored
。如果它没有返回值,DFS
将不会做任何事情,因为它从不返回值。Python通过引用传递,而不是通过值传递。出现在DFS()
中的已访问的是从numIslands()
传递的同一对象的不同名称。您可以在不更改原始值的情况下将某些内容重新分配给名称已访问
,但如果您更改名称已访问
所指的对象(通过使用已访问[i][j]=True更改其特定索引),则更改将持续,因为它是同一对象。“就像是原作的复制品。不是这样吗?“不,你不是。你可以用创建一个副本,这是否回答了你的问题?Python通过引用传递,而不是通过值传递。出现在DFS()
中的访问的
是从numIslands()传递的同一对象的不同名称
。您可以在不更改原始值的情况下,将某些内容重新分配给名称已访问
,但如果更改名称已访问
所指的对象(通过使用已访问[i][j]=True更改其特定索引),则更改将持续,因为它是同一对象。”就像是一本原著。不是这样吗?“不,你不是。你可以用创建一个副本,这是否回答了你的问题?我们可以添加:``list.copy()``返回列表对象的浅拷贝
,而不是深拷贝
。深拷贝和浅拷贝之间的区别是:“浅拷贝构造一个新的复合对象,然后(尽可能地)`向其中插入对原始中找到的对象的引用。“和”深度副本构造一个新的复合对象,然后递归地向其中插入原始中找到的对象的副本“。来源:我们可以添加:``list.copy()```返回列表对象的浅拷贝
,而不是深拷贝
。深拷贝和浅拷贝之间的区别是:“浅拷贝构造一个新的复合对象,然后(尽可能)在其中插入对原始对象的引用。”和“深拷贝构造一个新的复合对象,然后,递归地将在原始文件中找到的对象的副本插入其中。源: