欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

我变了,你变不变?

程序员文章站 2022-04-14 18:26:06
我变了,你变不变? 内存相关的小知识 1. 列表(list)/字典(dict)/集合(set) 情况一: 修改内存中的元素,所有指向那个内存的值都会改变 情况二: 重新赋值不修改内存中的元素,只改变值的指向 2. 字符串(str)/元组(tuple) 只有情况二,只能重新赋值,不能修改 3. 总结 ......

我变了,你变不变?

内存相关的小知识

  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}]
    """