Python:初学者系列:关于列表中包含列表在复制时会自然而然地思考

初学者系列

关于列表中包含列表在复制时会自然而然地思考

	listA = [1, [2, 3, 4], 5]
	listB = listA[:]
	listB[0] = 111
	print(listA)
	print(listB)
#结果
	[1, [2, 3, 4], 5]
	[111, [2, 3, 4], 5]

上面这些代码很容易出现在各种python初学者的书中,我所使用的《Python编程从入门到实践》的三件套也一样。 他似乎让人简单地相信了:“啊!我创建了一个全新的列表,这是一个深拷贝(deepcopy),耶!”
并且在书中P55的4.4.3中明确说明了使用上述方法会创建一个原有列表的副本。可为什么对上述代码继续执行下述操作时,会产生一个意想不到的错误。

	listB[1][0] = 8
	print(listA)
#结果
	[1 ,[8, 3, 4], 5]

这是为什么呢,不是说好了会新copy出一个副本吗?
是谁欺骗了你!
所以需要了解的是:python中所有的变量更类似于是对于一个“值”的标签,并且这是可以简单验证,就可以很好地说服别人。你只需要输入以下代码:

	print(listA[0] is listB[0])#listA的第一个元素(数值)和listB中第一个元素(数值)是同一个吗?
	print(listA[1] is listB[1]) 
#结果
	True
	True

这说明了什么呢?
表示就算真的listB是一个listA的新的副本,但其中不论是值还是列表(即列表中的列表)都是同一个,如果你还是不相信那你可以详细查询每一个参数的地址。

	print(id(listA))
	print(id(listB))
	print(id(listA[0]))
	print(id(listB[0]))
	print(id(listA[1]))
	print(id(listB[1]))
#结果
	3259111553032		#listA的地址
	3259111808328		#listB的地址
	140709651476224		#listA中第一个元素(数值)的地址
	140709651476224		#listB中第一个元素(数值)的地址
	3259141103880		#listA中第二个元素(列表)的地址
	3259141103880		#listB中第二个元素(列表)的地址

这应该足以说服你了吧!

上述结果中的数字你们肯定不会和我一样,但其中彼此相同的id就足以说明其中的逻辑

说明他们其实都是相当于一个标签。也就是说当我们在第一步中执行“listB[0] = 111”时,只是改动了listB第一个位置的标签,让它指向了111。不论是listA还是listB它们的第二个元素的标签都是指向[2,3,4]这个列表。
而当我们进行“listB[1][0] = 8”时,我们相当于通过listB的第二个标签索引到了这个列表 [2,3,4] ,并且在中索引到了 [2,3,4] 的第一个标签,并修改了这个标签对应的值,将 2 >>8。

	listA                                     listB
	[  0  ]  ------>        1        <------  [  0  ]
	[  1  ]  ------>  [I don't care] <------  [  1  ]
	[  2  ]  ------>        1        <------  [  2  ]
"""执行
	listB[0] = 111
"""
	listA                                     listB
	[  0  ]  ------>        1                 [  0  ]  ------>  111
	[  1  ]  ------>  [I don't care] <------  [  1  ]
	[  2  ]  ------>        1        <------  [  2  ]
"""执行
	listB[1][0] = 8
"""
	listA                                     listB
	[  0  ]  ------>        1                 [  0  ]  ------>  111
	[  1  ]  ------>  [I don't care] <------  [  1  ]
	[  2  ]  ------>        1        <------  [  2  ]
"""
	请问修改了listA还有listB中的标签吗?
	你只是对[I dont't care]进行了修改,我都说了我I don't care了,你还指望你修改了能改变什么吗?
	死舔狗!
"""

你想要改变listB[1],想和listA[1]彻底毫无关联,并且不改变它的值仅仅需要重新赋值即可

	listB[1] = [2, 3, 4]
	print(id(listA[1]))
	print(id(listB[1]))
	listB[1][0] = 8
	print(listA)
#结果
	3259110893320
	3259141078280
	[1, [2, 3, 4], 5]

拿下!!!

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值