难点和错误

在“有时赋值不是你想象”那个帖子里,我们讨论了对于数值型和字符型变量,互相赋值不影响变量的单独使用,比如:

nStr = 'cheer'
mStr = nStr

print(mStr, nStr)    # 运行结果是:cheer cheer
mStr = 'happy'
print(mStr, nStr)    # 运行结果是:happy cheer
 

互相赋值使得mStr和nStr两个变量短暂的拥有相同的值,之后插肩而过,各自精彩相忘于江湖。

而对于列表、集合、字典类型的变量,情况就不同了,一旦互相赋值就死死纠缠无法分开,我也很无奈呀。不信把它们三个类型变量都拎出来溜溜:

nList = [1, 3, 6, 9, 12]
mList = nList
# 列表变量互相赋值
mList.append(15)
# 列表mlist添加一个新元素
print(mList)            # 显示列表mList的内容为[1, 3, 6, 9, 12, 15],符合预期
print(nList)            # 显示nList的内容也是[1, 3, 6, 9, 12, 15],不符合预期

nSet = {1, 3, 6, 9, 12}
mSet = nSet             # 集合变量互相赋值
mSet.add(15)            # 加一个元素到集合mSet
print(nSet)             # {1, 3, 6, 9, 12, 15}
print(mSet)             # 也是{1, 3, 6, 9, 12, 15}

nDic = {'红楼梦':'曹雪芹', '西游记':'吴承恩', '三国演义':'罗贯中'}
mDic = nDic             # 字典变量互相赋值
mDic.update({'水浒传':'施耐庵'})      # 加一个元素到字典变量
print(mDic)
# {'红楼梦': '曹雪芹', '西游记': '吴承恩', '三国演义': '罗贯中', '水浒传': '施耐庵'}
print(nDic)
# 也是{'红楼梦': '曹雪芹', '西游记': '吴承恩', '三国演义': '罗贯中', '水浒传': '施耐庵'}
 

原因在于列表变量、集合变量还有字典变量里面并不是存放数据的数据单元,而是存放指向数据单元的地址。

mList = nList、mSet = nSet、mDic = nDic这些行为是在变量间分享地址,使得两个变量存放同样的地址,象指针一样指向同样的数据单元。之后改变数据单元里的数据并没有改变两个变量指向同样数据单元的现实。用print()输出变量内容,确切的说应该是输出变量所指向的数据,既然都指向同样的数据,那自然输出内容也相同。

难道这三个类型的变量就不能互相赋值了么?

当然可以,只需稍稍处理下。

nList = [1, 3, 6, 9, 12]
mList = list(nList)
mList.append(15)
print(mList)       # [1, 3, 6, 9, 12, 15]
print(nList)       # [1, 3, 6, 9, 12]

nSet = {1, 3, 6, 9, 12}
mSet = set(nSet)
mSet.add(15)
print(nSet)        # {1, 3, 6, 9, 12}
print(mSet)        # {1, 3, 6, 9, 12, 15}

nDic = {'红楼梦':'曹雪芹', '西游记':'吴承恩', '三国演义':'罗贯中'}
mDic = dict(nDic)
mDic.update({'水浒传':'施耐庵'})
print(mDic)
# {'红楼梦': '曹雪芹', '西游记': '吴承恩', '三国演义': '罗贯中', '水浒传': '施耐庵'}
print(nDic)
# {'红楼梦': '曹雪芹', '西游记': '吴承恩', '三国演义': '罗贯中'}