• Python字典注意事项


    # 代码一
    list1 = []
    dict1 = {}
    for i in range(5):
        dict1 = {"one": i}
        list1.append(dict1)
    print(list1) # [{'one': 0}, {'one': 1}, {'one': 2}, {'one': 3}, {'one': 4}]
    
    # 看一下列表的id值
    for id_value in map(lambda x: id(x), list1):
        print(id_value)
    
    我的理解
    • 循环外部创建了一个空的字典和一个变量并进行赋值。我们知道在 Python 中,对象赋值实际上是对象的引用即,一个变量给另一个变量赋值时,传的是地址,所以就将dict1这个变量和{}这个空字典捆绑在了一起,或者说dict1指向了{}

    • for循环内每次字典的创建{"one": i}都会在内存中新开辟一块空间用来存放该字典,而每次的赋值操作又会将dict1这个变量指向新的字典如{"one":0}

    • 然后对list1进行append操作时,我的猜想(已证实)是进行 append 操作时,实际上追加的是该对象的引用,因此每次append时都会将每个字典的(引用)内存地址传入list1

    • 查看一下list1id (它可以返回对象的唯一标识) ['1593305955784','1593305955496','1593306802432'...],注意里面的 id 并不相同

    • 列表中包含各个不同字典的内存地址,因此最终生成的列表就是各个值都不相同的列表

     
     
     

    # 代码二
    list2 = []
    dict2 = {}
    for i in range(5):
        dict2["one"] = i
        print(dict2) # 依次输出 {'one': 0},{'one': 1},{'one': 2},{'one': 3},{'one': 4}
        list2.append(dict2)
    print(list2) # [{'one': 4}, {'one': 4}, {'one': 4}, {'one': 4}, {'one': 4}]
    
    # 看一下列表的id值
    for id_value in map(lambda x: id(x), list1):
        print(id_value)
    

    我的理解

    • 根据输出可以看出,dict2["one"] = i每一次都只是对字典dict2进行修改,最后保留了最后修改的结果,并没有像 代码一 那样新建一个字典
    • 试着分析一下过程
      • 先在内存中开一块区域放空字典并赋值给dict2(引用)
         
      • 每次循环都修改dict2所指向的那块区域
         
      • 之后将dict2所指向的内存中的字典的内存地址 append 至list2
         
      • 但是每一次的dict2["one"] = i并没有新建字典,始终是在对该字典的value进行重写,并没有新建字典,自始至终只有一个字典,所以每次append的都是同一个内存地址
         
      • 我们可以用来查看一下这个列表的 id, ['2966419766368','2966419766368','2966419766368'...],发现id 都是一样的
         
      • 因为由于一个key只能对应一个value,多次对一个key放入value,后面的值会把前面的值覆盖掉,因此最终list2的值就以最后一次修改字典的值为准。列表中包含同一个的内存地址,因此最终生成的列表就是各个值都相同的列表

     
    浅拷贝只拷贝了对象的引用,遇上这种情况可以深拷贝解决
     
     
    以上内容仅代表个人看法,不具有权威性,看看就好...

  • 相关阅读:
    有关 JavaScript 的 10 件让人费解的事情
    Apache ab介绍1
    Oracle Raw,number,varchar2... 转换
    Flex开发者需要知道的10件事
    linux命令之nice
    JavaIO复习和目录文件的复制
    使用php获取网页内容
    linux 安装sysstat使用iostat、mpstat、sar、sa
    SQL Injection 实战某基金
    ubuntu root锁屏工具
  • 原文地址:https://www.cnblogs.com/NoTrace/p/12580652.html
Copyright © 2020-2023  润新知