[问题] list与list[:]差异

楼主: ericrobin   2020-08-30 00:40:38
以前都没注意到两者不太一样
直到我跑了下面这段码
def subsets(self, nums):
def backtrack(start, end, tmp):
ans.append(tmp[:])
for i in range(start, end):
tmp.append(nums[i])
backtrack(i+1, end, tmp)
tmp.pop()
ans = []
backtrack(0, len(nums), [])
return ans
假如nums=[1,2,3]
照这段码跑下去, tmp能够随着函数的呼叫持续变动,
最后ans 会返回1,2,3 [[],[1],[1,2],[1,2,3],[1,3],[2],[2,3],[3]]
然而如果第三行的tmp[:]改为tmp
最后只会是[[],[],[],[],[],[],[],[]]
不知道两者间的差别在哪
而这差别除了在函数呼叫有影响外, 还有什么时候要注意呢
以往没特别打上[:]好像都没出过事@@
用type看了一下都是<class 'list'>
我猜会不会tmp只是类似这list开头的指标
而tmp[:]才是整段list的值?
作者: TuCH (谬客)   2020-08-30 02:11:00
是的 tmp只是指标 tmp[:] == tmp.copy()
作者: tsaiminghan (tsaiminghan)   2020-08-30 22:34:00
tmp[:]是浅复制(shallow copy)
作者: calvinvin (残月)   2020-08-31 10:07:00
没错,对变量赋值时其实是将变量指向某段内存位址,例如a=[1,2,3], b=a, c=a的意思是创出一段值为[1,2,3]的内存位置,然后将a指向它,b、c则跟a也一样指向它。透过a、b、c任一个变量使用method来修改[1,2,3]时,指向该处的a,b,c当然也就随之而变。而赋值为list[:]时则是建立一个新的内存位址,其值为list[:],修改原本的list当然就不会影响到这新的、独立的东西。所以你的程式码将list[:]改成list后,跑的结果是将ans一直append上tmp,而这个tmp指向的值则是你最后将tmp给pop完的空list。以上是我非本科系自学新手的理解,若有观念、名词错误烦请大大不吝纠正,若是我自以为而没回答的原po的问题,也先说抱歉@@

Links booklink

Contact Us: admin [ a t ] ucptt.com