前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python list拷贝赋值问题

python list拷贝赋值问题

作者头像
用户7886150
修改2021-01-27 15:23:29
1K0
修改2021-01-27 15:23:29
举报
文章被收录于专栏:bit哲学院

参考链接: Python list append()

在python中,用等号或者append方法进行list的赋值,实际上是将原list的引用赋给了新的变量,在后续使用append方法改变这两个list中的任何一个时,另一个也会同时改变: 

b = [0,1,2]

a = b

b.append(3)

print(a)

print(b)

>>a = [0,1,2,3]

>>b = [0,1,2,3]

a.append(4)

print(a)

print(b)

>>a = [0,1,2,3,4]

>>b = [0,1,2,3,4]

a[0]=5

>>a = [5,1,2,3,4]

>>b = [5,1,2,3,4]

用append方法把b添加进a也会发生同样的情况: 

a = []

b = [0,1,2]

a.append(b)

b.append(3)

print(a)

print(b)

>>a = [[0,1,2,3]]

>>b = [0,1,2,3]

a[0].append(4)

print(a)

print(b)

>>a = [[0,1,2,3,4]]

>>b = [0,1,2,3,4]

避免这种情况的方法是用另一个变量把b给copy出来: 

b = [0,1,2]

c = b.copy()

a = c

b.append(3)

print(a)

print(b)

print(c)

>>a = [0,1,2]

>>b = [0,1,2,3]

>>c = [0,1,2]

a.append(4)

print(a)

print(b)

print(c)

>>a = [0,1,2,4]

>>b = [0,1,2,3]

>>c = [0,1,2,4]

把a=c这行换成a.append(c)情况类似,但是这好像是append这类直接修改列表的方法才会出现的(除append之外还有pop),如果重新给b赋其他值,则不会出现上述问题:(应该是重新赋值时新建了一块地址叫b,切断了a和之前的变量b的关系) 

b = [0,1,2]

a = b

b = b[1:]

print(a)

print(b)

>>a = [0,1,2]

>>b = [1,2]

b = [3,4,5]

print(a)

print(b)

>>a = [0,1,2]

>>b = [3,4,5]

如果b是个二维list呢? 

b = [[0,1],[2,3]]

a = b.copy()

id(a)==id(b)

>>False

id(a[0])==id(b[0])

>>True

也就是说使用copy的时候,只是把a和b的地址分开了,他们里面实际的子列表还是引用的关系,修改其中一个子列表必然会影响到另一个: 

a[0].append(2)

print(a)

print(b)

>>a = [[0,1,2],[2,3]]

>>b = [[0,1,2],[2,3]]

但是修改a却不会同时修改b: 

a.append(4)

>>a = [[0,1,2],[2,3],4]

>>b = [[0,1,2],[2,3]]

所以遇到二维list的时候乖乖用deepcopy()吧。 总结一下: 1.用等号(或appne)将list赋值:a=b(a.append(b)),a和b互为引用关系,id(a)==id(b), id(a[0])==id(b[0])。 2.用copy将list赋值:a=b.copy(),则id(a)!=id(b), id(a[0])==id(b[0])。 3.当id(a)==id(b)时,直接修改a如a.append(x)这类方法,会同时修改b,改变a中的值如a[0]=x,也会同时修改b。 4.当id(a)!=id(b), id(a[0])==id(b[0])时,直接修改a如a.append(x)这类方法,或者修改a[0],都不会同时修改b,但操作到a[0]中的元素,改变a[0]中的值如a[0][0]=x,会同时修改b。 5.也就是说,当两个变量的某一层次是引用关系时,使用append、pop修改当前层级会同时修改另一变量,使用直接赋值修改当前层级不会同时修改另一变量。当两个变量的某一层次是引用关系时(id(a)==id(b)),使用赋值修改下一层级的值(a[0]=x),会同时修改另一变量。 6.用深拷贝a=b.deepcopy()肯定没错。 感觉list真是个神奇的东西。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档