• 我变了,你变不变?


    内存相关的小知识

    1. 列表(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不改变
        
        • 重新赋值不修改内存中的元素,只改变值的指向
    2. 字符串(str)/元组(tuple)

      • 只有情况二,只能重新赋值,不能修改
    3. 总结

      • 在python中,为了提高性能,值若是以下情况(python小数据池),就不重新开辟内存

        • 常用数字:-5~256
        • 简单字符串:如'alex',除去 'alex' * 3(数字大于1) 这种情况
      • == 比较的是值是否相等,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
        
        • 注:python小数据池除外
    4. 练习题

      #看代码写结果并解释原因
      #练习题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}]
      """
      
      
    勤勤恳恳更博,点点滴滴记录
  • 相关阅读:
    性能测试监控指标-数据库
    cpu 故障定位
    ubuntu安装boost
    固定IP下虚拟机网卡配置及ssh
    零基础天池新闻推荐初学-04-排序模型+模型融合的简单学习(TODO 待进一步完善)
    零基础天池新闻推荐初学-04-特征工程(制作特征列和标签列,转为监督学习)
    零基础天池新闻推荐初学-03-多路召回
    零基础天池新闻推荐初学-02-数据分析
    零基础天池新闻推荐初学-01-赛题理解&Baseline
    初学推荐系统-06- GBDT+LR模型
  • 原文地址:https://www.cnblogs.com/zengyi1995/p/10651806.html
Copyright © 2020-2023  润新知