列表(list)/字典(dict)/集合(set)
情况一:
v1 = [1,2,3]
v2 = v1
v1.append(4) #增加
print(v2) #[1,2,3,4]
#在v1里面修改(增加/删除),v2也跟着改变
情况二:
v1 = [1,2,3]
v2 = v1
v1 = [3,4,5] #重新赋值
print(v2) #[1,2,3]
#重新赋值v1,v2不改变
字符串(str)/元组(tuple)
总结
在python中,为了提高性能,值若是以下情况(python小数据池),就不重新开辟内存
== 比较的是值是否相等,is 比较的是内存地址是否相等
#例1:
v1 = [1,2]
v2 = [1,2]
v1 == v2 #True
v1 is v2 #False
#例2:
v1 = [1,2]
v2 = v1
v1 == v2 #True
v1 is v2 #True
练习题
#看代码写结果并解释原因
#练习题1:
v1 = {'k1':'v1','k2':[1,2,3]}
v2 = v1
v1['k1'] = 'wupeiqi'
print(v2)
"""
结果:
{'k1':'wupeiqi','k2':[1,2,3]}
原因:
因为v1和v2指向的内存地址是同一个,
修改v1里面的元素,相当于修改的是内存地址中的元素,
所以v2也会跟着改变,因此输出的v2也改变了
"""
#练习题2:
v1 = '人生苦短,我用Python'
v2 = [1,2,3,4,v1]
v1 = "人生苦短,用毛线Python"
print(v2)
"""
结果:
[1,2,3,4,'人生苦短,我用Python']
原因:
一开始,v2中的v1和v1指向的内存地址是同一个,
给v1重新赋值,只改变v1的指向,相当于v1指向了一个新的内存地址,
而v2中v1的还是指向原来的那个内存地址,所以输出的v2不改变
"""
#练习题3:
info = [1,2,3]
userinfo = {'account':info, 'num':info, 'money':info}
info.append(9)
print(userinfo)
info = "题怎么这么多"
print(userinfo)
"""
结果:
{'account':[1,2,3,9], 'num':[1,2,3,9], 'money':[1,2,3,9]} #第一个userinfo
{'account':[1,2,3,9], 'num':[1,2,3,9], 'money':[1,2,3,9]} #第二个userinfo
原因:
一开始,userinfo中的info和info指向的内存地址是同一个,
先修改info里面的元素,相当于修改的是内存地址中的元素,
所以userinfo中info也会跟着改变,因此输出的第一个userinfo也改变了,
再给info重新赋值,只改变info的指向,相当于info指向了一个新的内存地址,
而userinfo中info的还是指向原来的那个内存地址,
所以输出的第二个userinfo不再改变,还是第一个userinfo的值
"""
#练习题4:
info = [1,2,3]
userinfo = [info,info,info,info,info]
info[0] = '不仅多,还特么难呢'
print(info,userinfo)
"""
结果:
['不仅多,还特么难呢',2,3] #info
[['不仅多,还特么难呢',2,3],['不仅多,还特么难呢',2,3],['不仅多,还特么难呢',2,3],
['不仅多,还特么难呢',2,3],['不仅多,还特么难呢',2,3]] #userinfo
原因:
userinfo中的info和info指向的内存地址是同一个,
修改info里面的元素,相当于修改的是内存地址中的元素,
所以userinfo中info也会跟着改变,因此输出的info和userinfo都改变了
"""
#练习题5:
info = [1,2,3]
userinfo = [info,info,info,info,info]
userinfo[2][0] = '闭嘴'
print(info,userinfo)
"""
结果:
['闭嘴',2,3] #info
[['闭嘴',2,3],['闭嘴',2,3],['闭嘴',2,3],['闭嘴',2,3],['闭嘴',2,3]] #userinfo
原因:
userinfo中的info和info指向的内存地址是同一个,
修改userinfo中的info里面的元素,相当于修改的是内存地址中的元素,
所以所有info都会跟着改变,因此输出的info和userinfo都改变了
"""
#练习题6:
info = [1, 2, 3]
user_list = []
for item in range(10):
user_list.append(info)
info[1] = "是谁说Python好学的?"
print(user_list)
"""
结果:
[[1, "是谁说Python好学的?", 3],[1, "是谁说Python好学的?", 3],
[1, "是谁说Python好学的?", 3],[1, "是谁说Python好学的?", 3],
[1, "是谁说Python好学的?", 3],[1, "是谁说Python好学的?", 3],
[1, "是谁说Python好学的?", 3],[1, "是谁说Python好学的?", 3],
[1, "是谁说Python好学的?", 3],[1, "是谁说Python好学的?", 3]]
原因:
for循环让user_list循环追加info了10次,此时相当于
user_list = [info,info,info,info,info,info,info,info,info,info],
userinfo中的info和info指向的内存地址是同一个,
修改info里面的元素,相当于修改的是内存地址中的元素,
所以userinfo中info也会跟着改变,因此输出的userinfo改变了
"""
#练习题7:
data = {}
for item in range(10):
data['user'] = item
print(data)
"""
结果:
{'user':9}
原因:
对于for循环,第一次循环时给data添加了'user':0这个元素,
后面的每一次循环,都在修改'user'这个键所对应的值,
最后一次循环将值修改为9,所以输出结果为{'user':9}
"""
#练习题8:
data_list = []
data = {}
for item in range(10):
data['user'] = item
data_list.append(data)
print(data_list)
"""
结果:
[{'user':9},{'user':9},{'user':9},{'user':9},{'user':9},
{'user':9},{'user':9},{'user':9},{'user':9},{'user':9}]
原因:
对于for循环,
第一次循环时,给data添加了'user':0这个元素,即data = {'user':0},
再将date追加到data_list中,此时data_list = [date],即data_list = [{'user':0}],
此时data_list中的date和data指向的内存地址是同一个,
第二次循环时,修改了date中'user'对应的值,此时data = {'user':1},
再将date追加到data_list中,此时data_list = [date,date],
因为data_list中的date和data指向的内存地址是同一个,
修改date里面的元素,相当于修改的是内存地址中的元素,
所以data_list中date也会跟着改变,因此data_list中第一个date的值也改变了,
即data_list = [{'user':1},{'user':1}],
同理,每循环一次,date就修改一次,data_list中所有date都跟着改变,
最后一次循环时,将'user'对应的值修改为9,所以data = {'user':9},
此时,data_list中所有date都改变了,都变为{'user':9},
即输出的data_list = [{'user':9},{'user':9},{'user':9},{'user':9},{'user':9},
{'user':9},{'user':9},{'user':9},{'user':9},{'user':9}]
"""
#练习题9:
data_list = []
for item in range(10):
data = {}
data['user'] = item
data_list.append(data)
print(data_list)
"""
结果:
[{'user':0},{'user':1},{'user':2},{'user':3},{'user':4},
{'user':5},{'user':6},{'user':7},{'user':8},{'user':9}]
原因:
第一次循环时,给data添加了'user':0这个元素,即data = {'user':0},
再将date追加到data_list中,此时data_list = [date],即data_list = [{'user':0}],
此时data_list中的date和data指向的内存地址是同一个,
第二次循环时,给date重新赋值,只改变date的指向,相当于date指向了一个新的内存地址,
再给data添加了'user':1这个元素,即data = {'user':1},
再将date追加到data_list中,此时data_list = [date,date],
此时data_list中的第一个date还是指向的原来那个内存地址,所以第一个date不再改变,
此时data_list中的第二个date和data指向的内存地址都是新的内存地址,是同一个,
同理,依次循环,每循环一次,就给date重新赋值一次,
就相当于每次循环都重新开辟了一个新的地址给date,
而data_list中前面date还是分别指向它们原来的内存地址,所以都不再改变,
最后一次循环时,data = {'user':9},data_list中前面date都不再改变了,
只把新的date再追加进去,即输出的data_list =
[{'user':0},{'user':1},{'user':2},{'user':3},{'user':4},
{'user':5},{'user':6},{'user':7},{'user':8},{'user':9}]
"""
原文:https://www.cnblogs.com/zengyi1995/p/10651806.html