我无法找到关于这个非常简单的程序中发生的事情的简明信息:
print 'case 1'
# a and b stay different
a = [1,2,3]
b = a
b = [4,5,6]
print 'a =',a
print 'b =',b
print
print 'case 2'
# a and b becomes equal
a = [1,2,3]
b = a
b[0] = 4
b[1] = 5
b[2] = 6
print 'a =',a
print 'b =',b
print
print 'case 3'
# a and b stay different now
a = [1,2,3]
b = a[:]
b[0] = 4
b[1] = 5
b[2] = 6
print 'a =',a
print 'b =',b
print
print 'case 4'
# now the funny thing
a=[1,2,[3]]
b=a[:]
b[0] = 4
b[1] = 5
b[2][0] = 6 # this modifies b and a!!!
这个简单测试的输出是:
case 1
a = [1, 2, 3]
b = [4, 5, 6]
case 2
a = [4, 5, 6]
b = [4, 5, 6]
case 3
a = [1, 2, 3]
b = [4, 5, 6]
case 4
a = [1, 2, [6]]
b = [4, 5, [6]]
我显然不明白python如何处理每个案例。任何人都可以提供一个链接,以便我可以阅读它,或者对正在发生的事情做一个简短的解释吗?
非常感谢。
答案 0 :(得分:9)
这是a fantastic visualization tool for python code。
在其中运行您的代码,一切都应该在一分钟内变得清晰。
答案 1 :(得分:6)
这里有两件重要的事情:
当您发现a
和b
都被修改时,那是因为它们都指向同一个对象。您可以id(a)
和id(b)
进行确认。
关于示例,请注意a[:]
将创建一个新对象,该对象是a
的副本。但是,它将是浅拷贝,而不是深拷贝。这解释了为什么在示例4中,您仍然可以同时修改a
和b
。它们指向不同的列表对象,但是一个元素是由它们共享的另一个列表。
答案 2 :(得分:4)
案例1:名称b
正在反弹。
案例2:a
和b
绑定到同一个对象。
案例3:a
的浅表副本绑定到b
。列表不同,但列表中的对象是相同的。
案例4:a
的浅表副本绑定到b
,然后其中一个对象发生变异。
重新绑定不会发生变异,并且变异不会重新绑定。
答案 3 :(得分:3)
print 'case 1'
# a and b stay different
a = [1,2,3]
b = a #At this point 'b' and 'a' are the same,
#just names given to the list
b = [4,5,6] #At this point you assign the name 'b' to a different list
print 'a =',a
print 'b =',b
print
print 'case 2'
# a and b becomes equal
a = [1,2,3] #At this point 'b' and 'a' are the same,
#just names given to the list
b = a
b[0] = 4 #From here you modify the list, since both 'a' and 'b'
#reference the same list, you will see the change in 'a'
b[1] = 5
b[2] = 6
print 'case 3'
# a and b stay different now
a = [1,2,3]
b = a[:] #At this point you COPY the elements from 'a' into a new
#list that is referenced by 'b'
b[0] = 4 #From here you modify 'b' but this has no connection to 'a'
b[1] = 5
b[2] = 6
print 'a =',a
print 'b =',b
print
print 'case 4'
# now the funny thing
a=[1,2,[3]]
b=a[:] #At this point you COPY the elements from 'a' into a new
#list that is referenced by 'b'
b[0] = 4 #Same as before
b[1] = 5
b[2][0] = 6 # this modifies b and a!!! #Here what happens is that 'b[2]' holds
#the same list as 'a[2]'. Since you only modify the element of that
#list that will be visible in 'a', try to see it as cases 1/2 just
#'recursively'. If you do b[2] = 0, that won't change 'a'