Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.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 - Fatal编程技术网

python中的列表行为是不可理解的

python中的列表行为是不可理解的,python,Python,我想了解python中的小片段: >>> x = ['foo', [1,2,3], 10.4] >>> y = list(x) >>> y[0] 'foo' >>> y[0] = "fooooooo" >>> y[1] [1, 2, 3] >>> y[1][0]=4 >>> print x ['foo', [4, 2, 3], 10.4] >>> pri

我想了解python中的小片段:

>>> x = ['foo', [1,2,3], 10.4]
>>> y = list(x)
>>> y[0]
'foo'
>>> y[0] = "fooooooo"
>>> y[1]
[1, 2, 3]
>>> y[1][0]=4
>>> print x
['foo', [4, 2, 3], 10.4]
>>> print y
['fooooooo', [4, 2, 3], 10.4]
>>> z = ['foo', [1,2,3], 10.4]
>>> x = ['foo', [1,2,3], 10.4]
>>> y = list(x)
>>> y[0] = "fooooooo"
>>> y[1]
[1, 2, 3]
>>> y[1][0]=4
>>> print x
['foo', [4, 2, 3], 10.4]
>>> print y
['fooooooo', [4, 2, 3], 10.4]
>>> print z
['foo', [1, 2, 3], 10.4]
>>> y = list(z)
>>> y[1][0]=6
>>> print y
['foo', [6, 2, 3], 10.4]
>>> y = list(z)
>>> print z
['foo', [6, 2, 3], 10.4]
>>> print x
['foo', [4, 2, 3], 10.4]
这是怎么回事。
如果将y的列表元素更改为x。这可能是python的基础,但我仍然没有掌握这一点。我猜您唯一感到困惑的是,设置一个变量的嵌套列表的元素将更改所有其他变量的嵌套列表。原因很简单:Python在每个变量中使用相同的嵌套列表(如中所示,完全相同的内存)。当您说
y=list(x)
时,Python将
x
的所有原子元素复制到
y
中,但只复制对嵌套列表的引用。由于相同的嵌套列表在任何地方都使用,因此在一个地方修改它会在任何地方修改它

通过玩
l1=[0]*3
l2=[[0]]*3
,您也可以看到类似的行为;
l1
l2
行为方式之间的差异是您观察到的行为的另一个例子

>>> x = ['foo', [1,2,3], 10.4]
>>> y = list(x)
y
x
的副本
y[1]
包含列表
[1,2,3]
x
中引用的副本。因此
y[1]
x[1]
是对同一列表的两个引用

y = list(x)
上面的语句创建列表
x
的浅拷贝

从:

浅复制构造一个新的复合对象,然后(尽可能)向其中插入对原始对象的引用

在这里,您确实获得了一个新对象
y
,但由于其中的列表是一个可变对象,因此您获得了对原始对象的引用。而且,如果继续创建这些浅表副本,列表对象将在所有副本之间共享

您可以使用
id
进行检查:

>>> id(x)
140183460314288
>>> id(y)
140183460372992        # this is different from y
>>> id(x[1])
140183460314864
>>> id(y[1])           # this is same as x[1] 
140183460314864
>>> y1 = list(y)       # another shallow copy from y
>>> id(y1[1]) 
140183460314864        # this is still same  
如果您希望在不影响
x
的情况下修改
y
的内容,则需要执行
deepcopy

>>> >>> from copy import deepcopy
>>> z = deepcopy(x)
>>> id(z[1])
140183460405400        # this is different now because of deepcopy

您可以看到此id不同于
id(x[1])
,现在如果您尝试修改内容,它们将不会反映在
x

中。好吧,但为什么在XB中y[0]=“foooooo”的值没有更改,因为您正在执行赋值,而且字符串是不可变的,它将创建一个新对象。您可以检查
id(y[0])
的值。更改其值后,它将不同。因为字符串是不可变的:请尝试
s='abc'
,然后
s[0]='d'
,您将得到一个错误。复制
x
时会得到一个新字符串(复制),因此
x[0]
y[0]
是两个不同的字符串,而
x[1]
y[1]
或对同一(可变)列表的两个引用。