Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 原始列表的元素在深度副本发生更改时发生更改_Python_Python 2.7 - Fatal编程技术网

Python 原始列表的元素在深度副本发生更改时发生更改

Python 原始列表的元素在深度副本发生更改时发生更改,python,python-2.7,Python,Python 2.7,我有一个全局列表(列表)变量。我将全局列表的浅表副本作为参数发送给另一个函数 令人惊讶的是,当我从调用的函数中的参数中删除一些元素时,原始列表会发生变化 有人能告诉我为什么会发生这种情况,以及如何防止这种情况发生吗 以下是简化的代码示例: def saveCandidateRoutes(candidateRoutes): for route in candidateRoutes: if route: # check if the list,

我有一个全局列表(列表)变量。我将全局列表的浅表副本作为参数发送给另一个函数

令人惊讶的是,当我从调用的函数中的参数中删除一些元素时,原始列表会发生变化

有人能告诉我为什么会发生这种情况,以及如何防止这种情况发生吗

以下是简化的代码示例:

def saveCandidateRoutes(candidateRoutes):

        for route in candidateRoutes:
            if route:       # check if the list, 'route', is empty. 
                tweetId = route.pop(0)
                stanox = route.pop(-1)
                ....

def main():

        global allCandidatePaths

        copyOfAllCandidatePaths= list(allCandidatePaths) # making a deep copy 
        result = saveCandidateRoutes(copyOfAllCandidatePaths)

我想你对这些条款感到困惑

浅复制是一种复制类型,其中复制列表的元素仍然绑定到与原始列表元素相同的内存值

你要找的是deepcopy

而且:
我想你对这些术语感到困惑

浅复制是一种复制类型,其中复制列表的元素仍然绑定到与原始列表元素相同的内存值

你要找的是deepcopy

而且:
浅层副本复制对象,但不复制其任何属性。对于列表,这意味着它的元素被分配给新列表的元素。如果元素是int,则会得到一个全新的列表,因为int是一个基元类型*,因此不需要复制它。如果元素是列表,就像在二维列表中一样,它们将被指定给副本,因此每个元素有两个引用,每个列表中有一个引用。如果要复制内部列表的元素,则需要一个深度副本,它递归地复制每个对象的属性(在本例中为元素)


*实际上,基本类型和非基本类型之间没有区别,但这与本解释范围内的工作方式相同。

浅拷贝复制对象,但不复制其任何属性。对于列表,这意味着它的元素被分配给新列表的元素。如果元素是int,则会得到一个全新的列表,因为int是一个基元类型*,因此不需要复制它。如果元素是列表,就像在二维列表中一样,它们将被指定给副本,因此每个元素有两个引用,每个列表中有一个引用。如果要复制内部列表的元素,则需要一个深度副本,它递归地复制每个对象的属性(在本例中为元素)


*实际上,基本类型和非基本类型之间没有区别,但这与本解释范围内的工作方式相同。

python使用对对象的引用,这意味着
AllCandidatePath
candidateRoutes
都指向内存中的相同列表,您可以使用这两个选项来更改列表

为了防止这种情况发生,请在函数的开头添加此指令
candidateRoutes=list(candidateRoutes)
list()
函数将在内存中创建原始列表的另一个副本,并将其引用分配给
candidateRoutes


因此,当您使用
candidateRoutes
时,您将不会处理主函数中的原始列表,而是处理另一个列表。

python使用对对象的引用,这意味着
allCandidatePaths
candidateRoutes
都指向内存中的相同列表,您可以使用这两个选项来更改列表

为了防止这种情况发生,请在函数的开头添加此指令
candidateRoutes=list(candidateRoutes)
list()
函数将在内存中创建原始列表的另一个副本,并将其引用分配给
candidateRoutes


因此,当您使用
candidateRoutes
时,您将不会处理主功能中的原始列表,而是处理另一个列表。

我认为您需要一个关于浅拷贝和深拷贝的快速提醒,以及如何制作深拷贝

>>> a = [[1,2], [3,4]] # a list of mutable elements
>>> b = a[:]
>>> c = list(a)
b
c
都是
a
的浅拷贝,您可以检查
a
b
c
是否是不同的对象,因为它们不共享相同的
id

>>> id(a)
140714873892592
>>> id(b)
140714810215672
>>> id(c)
140714873954744
然而,
a
b
c
的每个元素仍然是我们在定义a时创建的列表
[1,2]
[3,4]
的参考。当我们对列表中的一个项目进行变异时,这一点变得很清楚:

>>> c[1][1] = 42
>>> a
[[1, 2], [3, 42]]
>>> b
[[1, 2], [3, 42]]
>>> c
[[1, 2], [3, 42]]
如您所见,第二个列表的第二个元素在
a
b
c
中发生了更改。 现在,要制作
a
的深度副本,您有几个选项。一种是列表理解,您可以在其中复制每个子列表:

>>> d = [sublist[:] for sublist in a]
>>> d
[[1, 2], [3, 42]]
>>> d[1][1] = 23
>>> d
[[1, 2], [3, 23]]
>>> a
[[1, 2], [3, 42]]
如您所见,
a
中的42没有变为
23
,因为
a
d
中的第二个列表是不同的对象:

>>> id(a[1])
140714873800968
>>> id(d[1])
140714810230904
另一种创建深度副本的方法是使用
copy.deepcopy

>>> from copy import deepcopy
>>> e = deepcopy(a)
>>> e
[[1, 2], [3, 42]]
>>> e[1][1] = 777
>>> e
[[1, 2], [3, 777]]
>>> a
[[1, 2], [3, 42]]

我想你需要一个关于浅拷贝和深拷贝的快速提醒,以及如何制作深拷贝

>>> a = [[1,2], [3,4]] # a list of mutable elements
>>> b = a[:]
>>> c = list(a)
b
c
都是
a
的浅拷贝,您可以检查
a
b
c
是否是不同的对象,因为它们不共享相同的
id

>>> id(a)
140714873892592
>>> id(b)
140714810215672
>>> id(c)
140714873954744
然而,
a
b
c
的每个元素仍然是我们在定义a时创建的列表
[1,2]
[3,4]
的参考。当我们对列表中的一个项目进行变异时,这一点变得很清楚:

>>> c[1][1] = 42
>>> a
[[1, 2], [3, 42]]
>>> b
[[1, 2], [3, 42]]
>>> c
[[1, 2], [3, 42]]
如您所见,第二个列表的第二个元素在
a
b
c
中发生了更改。 现在,要制作
a
的深度副本,您有几个选项。一种是列表理解,您可以在其中复制每个子列表:

>>> d = [sublist[:] for sublist in a]
>>> d
[[1, 2], [3, 42]]
>>> d[1][1] = 23
>>> d
[[1, 2], [3, 23]]
>>> a
[[1, 2], [3, 42]]
如您所见,
a
中的42没有改变t