我正在编写一个py脚本,它从csv文件中读取行,操纵它们并将它们放回原处。到目前为止,我有csv列出转换工作。
我遇到的问题是当我遍历临时列表时,for循环会更改所有临时列表,而不仅仅是我想要的那个。这是我想说的一个简单的例子。
>>> l = [['hi', 'ho'],['no', 'go']]
>>> t = []
>>> y = []
>>>
>>> for row in l:
... row[0] = '123'
... y.append(row)
... t.append(row)
...
>>> y
[['123', 'ho'], ['123', 'go']]
>>> t
[['123', 'ho'], ['123', 'go']]
所以上述内容很简单(希望如此)。 (我们假设除了复制列表之外我还想做其他事情。只是想保持简单)。
但现在这是我没有得到的部分。
>>> z = []
>>> for row in y:
... row[0] = 'xxxx'
... z.append(row)
...
>>> z
[['xxxx', 'ho'], ['xxxx', 'go']]
>>> t
[['xxxx', 'ho'], ['xxxx', 'go']]
>>> y
[['xxxx', 'ho'], ['xxxx', 'go']]
当我想修改子列表中的第一部分并将其保存到新列表'z'时,它也会修改列表t!
这里发生了什么? z,y和t是否指向相同的内存位置?
此外,这里发生了什么?:
>>> for rowx in y:
... rowx[0] = 'x55x'
... z.append(rowx)
...
>>> z
[['xxxx', 'ho'], ['x55x', 'go'], ['x55x', 'go'], ['x55x', 'go']]
>>> t
[['xxxx', 'ho'], ['x55x', 'go']]
>>> y
[['xxxx', 'ho'], ['x55x', 'go']]
与上述问题类似,为什么y和t会发生变化?
提前致谢!!
答案 0 :(得分:7)
Python没有但引用。 row
是对l
或y
中实际元素的引用。变异row
变异该元素,并将其添加到另一个对象中添加原始元素。
答案 1 :(得分:4)
您的三个列表不同,但它们之间只共享两个元素:
>>> y[0] is t[0] is z[0]
True
>>> y[1] is t[1] is z[1]
True
如果is
运算符告诉您引用指向同一个对象,则无论您使用哪个引用,都会显示对该对象的更改。
要避免这种情况,请使用copy模块,如果您需要元素的副本:
>>> import copy
>>> a = copy.deepcopy(y)
>>> a
[['xxxx', 'ho'], ['xxxx', 'go']]
>>> a[0] is y[0]
False
>>> a[0][0] = 'copy!'
>>> y
[['xxxx', 'ho'], ['xxxx', 'go']]
答案 2 :(得分:0)
“z,y和t是否指向相同的内存位置?”
不,但是z [0],y [0]和t [0]是(虽然不称它为内存位置,但这不是C)。您将相同的列表['hi', 'ho']
附加到z,y和t。所以它是相同的列表。如果您不希望它是同一个列表,则必须先制作副本。