Python-浅/深拷贝问题:关于for循环中将字典添加到列表中出现字典值全部重复的问题

目    录

        一、问题再现

       1、问题阐述

        2、python代码

        3、运行结果 

        二、问题原因

        三、解决方法

        1、直接指向新字典对象(深拷贝)

        2、dict()转换成新字典对象(浅拷贝)

        3、切片[:](浅拷贝)

        4、copy()浅拷贝

        5、copy.copy()浅拷贝

        6、copy.deepcopy()深拷贝

        四、知识点


        一、问题再现

       1、问题阐述

        每次for循环过程中,列表中的所有字典值都和最新的字典赋值相同

        2、python代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/9/8 20:29
# software: PyCharm

t = {"tt": "DUCLAE"}
print(f"---t初始内存地址---{id(t)}")
list0 = [1, "33", 5, {"gg": "sad"}, [1, 2, 3]]
list1 = []
for n in list0:
    t["tt"] = n
    print(f"\t---t被赋值后内存地址---{id(t)}")
    print(f"\t---t被赋值后字典---{t}")
    list1.append(t)
    for i, n1 in enumerate(list1):
        print(f"\t---列表中第-{i + 1}-个内存地址---{id(n1)}")
        print(f"\t---列表中第-{i + 1}-个字典---{n1}")
    print(f"\t---list1---{list1}\n")

        3、运行结果 

---t初始内存地址---2090766940096
    ---t被赋值后内存地址---2090766940096
    ---t被赋值后字典---{'tt': 1}
    ---列表中第-1-个内存地址---2090766940096
    ---列表中第-1-个字典---{'tt': 1}
    ---list1---[{'tt': 1}]

    ---t被赋值后内存地址---2090766940096
    ---t被赋值后字典---{'tt': '33'}
    ---列表中第-1-个内存地址---2090766940096
    ---列表中第-1-个字典---{'tt': '33'}
    ---列表中第-2-个内存地址---2090766940096
    ---列表中第-2-个字典---{'tt': '33'}
    ---list1---[{'tt': '33'}, {'tt': '33'}]

    ---t被赋值后内存地址---2090766940096
    ---t被赋值后字典---{'tt': 5}
    ---列表中第-1-个内存地址---2090766940096
    ---列表中第-1-个字典---{'tt': 5}
    ---列表中第-2-个内存地址---2090766940096
    ---列表中第-2-个字典---{'tt': 5}
    ---列表中第-3-个内存地址---2090766940096
    ---列表中第-3-个字典---{'tt': 5}
    ---list1---[{'tt': 5}, {'tt': 5}, {'tt': 5}]

    ---t被赋值后内存地址---2090766940096
    ---t被赋值后字典---{'tt': {'gg': 'sad'}}
    ---列表中第-1-个内存地址---2090766940096
    ---列表中第-1-个字典---{'tt': {'gg': 'sad'}}
    ---列表中第-2-个内存地址---2090766940096
    ---列表中第-2-个字典---{'tt': {'gg': 'sad'}}
    ---列表中第-3-个内存地址---2090766940096
    ---列表中第-3-个字典---{'tt': {'gg': 'sad'}}
    ---列表中第-4-个内存地址---2090766940096
    ---列表中第-4-个字典---{'tt': {'gg': 'sad'}}
    ---list1---[{'tt': {'gg': 'sad'}}, {'tt': {'gg': 'sad'}}, {'tt': {'gg': 'sad'}}, {'tt': {'gg': 'sad'}}]

    ---t被赋值后内存地址---2090766940096
    ---t被赋值后字典---{'tt': [1, 2, 3]}
    ---列表中第-1-个内存地址---2090766940096
    ---列表中第-1-个字典---{'tt': [1, 2, 3]}
    ---列表中第-2-个内存地址---2090766940096
    ---列表中第-2-个字典---{'tt': [1, 2, 3]}
    ---列表中第-3-个内存地址---2090766940096
    ---列表中第-3-个字典---{'tt': [1, 2, 3]}
    ---列表中第-4-个内存地址---2090766940096
    ---列表中第-4-个字典---{'tt': [1, 2, 3]}
    ---列表中第-5-个内存地址---2090766940096
    ---列表中第-5-个字典---{'tt': [1, 2, 3]}
    ---list1---[{'tt': [1, 2, 3]}, {'tt': [1, 2, 3]}, {'tt': [1, 2, 3]}, {'tt': [1, 2, 3]}, {'tt': [1, 2, 3]}]


        二、问题原因

        1、字典用key-value来添加值时,如果每次的key相同,则相当于赋值,只是修改字典中该key所在的内存地址(引用)下的value,并不会在字典中添加新的key-value,所以for循环过程中,指向同一个内存地址(引用)的字典都会被修改。

        2、列表添加方法append()添加值时,相当于只会添加一个该值的内存地址(引用),所以for循环过程中,列表中添加的值都会被修改。


        三、解决方法

        1、直接指向新字典对象(深拷贝)

        (1)python代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/9/8 20:29
# software: PyCharm
import copy

t = {"tt": "DUCLAE"}
print(f"---t初始内存地址---{id(t)}")
list0 = [1, "33", 5, {"gg": "sad"}, [1, 2, 3]]
list1 = []
for n in list0:
    # 直接指向新字典对象,而不是赋值(深拷贝)
    t = {"tt": n}
    print(f"\t---t被赋值后内存地址---{id(t)}")
    list1.append(t)
    for i, n1 in enumerate(list1):
        print(f"\t---列表中第-{i + 1}-个内存地址---{id(n1)}")
        print(f"\t---列表中第-{i + 1}-个字典---{n1}")
    print(f"\t---list1---{list1}\n")

        (2)运行结果

---t初始内存地址---2250142758848
    ---t被赋值后内存地址---2250145875776
    ---列表中第-1-个内存地址---2250145875776
    ---列表中第-1-个字典---{'tt': 1}
    ---list1---[{'tt': 1}]

    ---t被赋值后内存地址---2250145876224
    ---列表中第-1-个内存地址---2250145875776
    ---列表中第-1-个字典---{'tt': 1}
    ---列表中第-2-个内存地址---2250145876224
    ---列表中第-2-个字典---{'tt': '33'}
    ---list1---[{'tt': 1}, {'tt': '33'}]

    ---t被赋值后内存地址---2250145911872
    ---列表中第-1-个内存地址---2250145875776
    ---列表中第-1-个字典---{'tt': 1}
    ---列表中第-2-个内存地址---2250145876224
    ---列表中第-2-个字典---{'tt': '33'}
    ---列表中第-3-个内存地址---2250145911872
    ---列表中第-3-个字典---{'tt': 5}
    ---list

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值