关于列表和字典的问题


index_num = persion_info.index(i)
                        dict_cur_perinfo = persion_info[index_num]
                        for title, info in dict_cur_perinfo.items():
                            print(title + ':' + info)
                            modi_name = input('请输入新的姓名:')
                            modi_phone = input('请输入新的手机号:')
                            modi_email = input('请输入新的邮箱:')
                            modi_address = input('请输入新的地址:')
                            dict_cur_perinfo.update(姓名=modi_name)
                            dict_cur_perinfo.update(手机号=modi_phone)
                            dict_cur_perinfo.update(电子邮箱=modi_email)
                            dict_cur_perinfo.update(联系地址=modi_address)
                            print(persion_info)

这段代码中persion_info是一个列表,dict_cur_perinfo是一个字典,将字典放入带列表中,然后通过下标调取列表persion_info中的字典,然后赋值给dict_cur_perinfo,然后通过updatedict_cur_perinfo进行一些更改。

问题是:对dict_cur_perinfo的更改最后还传到了列表persion_info中,这是什么原因?感觉只是对字典dict_cur_perinfo做的更改啊,列表只是将自己的元素赋值给dict_cur_perinfo了。

以下是完整的代码,仅做参考

# 定义一个列表来存通信人的信息,列表的每一个元素代表一个通讯人
persion_info = []
# 展示通讯录的功能
print('=' * 20)
print('欢迎使用通讯录')
print('1.添加联系人')
print('2.查看通讯录')
print('3.删除联系人')
print('4.修改联系人')
print('5.查找联系人')
print('6.退出')
print('=' * 20)
# 设计一个循环来输入、修改、查询等通信人的信息
while True:
    # 虽然使用列表存储信息,但是每条信息都是字典
    # 在列表里存储字典
    per_dict = {}
    # 定义一个变量来接受需要的功能序号
    fun_num = input('请输入功能序号:')
    if fun_num == '1':
        per_name = input('请输入联系人姓名:')
        per_phone = input('请输入联系人的手机号码:')
        per_email = input('请输入联系人的邮箱:')
        per_address = input('请输入联系人的地址:')
        if per_name.strip() == '':
            print('联系人名称不能为空!')
            # continue跳出本次循环 ,break跳出整个循环
            continue
        else:
            per_dict.update({'姓名': per_name,
                             '手机号': per_phone,
                             '电子邮箱': per_email,
                             '联系地址': per_address})
            # 字典存入到列表中
            persion_info.append(per_dict)
            print('保存成功!')
    elif fun_num in ['2', '3', '4', '5']:
        if len(persion_info) != 0:
            if fun_num == '2':
                for i in persion_info:
                    for title, info in i.items():
                        print(title + ':' + info)
            elif fun_num == '3':
                del_name = input('请输入要删除的联系人姓名:')
                for i in persion_info:
                    if del_name in i.values():
                        persion_info.remove(i)
                        print(persion_info)
                        print('删除成功!')
                    else:
                        print('该联系人不在通讯录中!')
            elif fun_num == '4':
                modi_info = input('请输入要修改联系人的姓名:')
                for i in persion_info:
                    if modi_info in i.values():
                        # 获取所在的位置索引
                        index_num = persion_info.index(i)
                        dict_cur_perinfo = persion_info[index_num]
                        for title, info in dict_cur_perinfo.items():
                            print(title + ':' + info)
                            modi_name = input('请输入新的姓名:')
                            modi_phone = input('请输入新的手机号:')
                            modi_email = input('请输入新的邮箱:')
                            modi_address = input('请输入新的地址:')
                            dict_cur_perinfo.update(姓名=modi_name)
                            dict_cur_perinfo.update(手机号=modi_phone)
                            dict_cur_perinfo.update(电子邮箱=modi_email)
                            dict_cur_perinfo.update(联系地址=modi_address)
                            print(persion_info)
            elif fun_num == '5':  # 查找联系人
                query_name = input('请输入要查找的联系人姓名:')
                for i in persion_info:
                    if query_name in i.values():
                        index_num = persion_info.index(i)
                for title, info in persion_info[index_num].items():
                    print(title + ":" + info)
        else:
            print('通讯录是空的!请输入一些联系人信息!')
            continue
    elif fun_num == '6':
        print('谢谢使用!')
        break

因为在Python中,字典是可变对象,它们是通过引用传递的,而不是通过值传递的。
因此,如果两个变量引用同一个字典对象,那么对其中一个变量所做的修改会影响另一个变量所引用的同一个字典对象。
如果原始列表不想被修改,可以使用深拷贝方式copy.deepcopy()。

import copy
persion_info = []
# 展示通讯录的功能
print('=' * 20)
print('欢迎使用通讯录')
print('1.添加联系人')
print('2.查看通讯录')
print('3.删除联系人')
print('4.修改联系人')
print('5.查找联系人')
print('6.退出')
print('=' * 20)
# 设计一个循环来输入、修改、查询等通信人的信息
while True:
    # 虽然使用列表存储信息,但是每条信息都是字典
    # 在列表里存储字典
    per_dict = {}
    # 定义一个变量来接受需要的功能序号
    fun_num = input('请输入功能序号:')
    if fun_num == '1':
        per_name = input('请输入联系人姓名:')
        per_phone = input('请输入联系人的手机号码:')
        per_email = input('请输入联系人的邮箱:')
        per_address = input('请输入联系人的地址:')
        if per_name.strip() == '':
            print('联系人名称不能为空!')
            # continue跳出本次循环 ,break跳出整个循环
            continue
        else:
            per_dict.update({'姓名': per_name,
                             '手机号': per_phone,
                             '电子邮箱': per_email,
                             '联系地址': per_address})
            # 字典存入到列表中
            persion_info.append(per_dict)
            print('保存成功!')
    elif fun_num in ['2', '3', '4', '5']:
        if len(persion_info) != 0:
            if fun_num == '2':
                for i in persion_info:
                    for title, info in i.items():
                        print(title + ':' + info)
            elif fun_num == '3':
                del_name = input('请输入要删除的联系人姓名:')
                for i in persion_info:
                    if del_name in i.values():
                        persion_info.remove(i)
                        print(persion_info)
                        print('删除成功!')
                    else:
                        print('该联系人不在通讯录中!')
            elif fun_num == '4':
                modi_info = input('请输入要修改联系人的姓名:')
                for i in persion_info:
                    if modi_info in i.values():
                        # 获取所在的位置索引
                        index_num = persion_info.index(i)
                        dict_cur_perinfo = copy.deepcopy(persion_info[index_num])
                        for title, info in dict_cur_perinfo.items():
                            print(title + ':' + info)
                            modi_name = input('请输入新的姓名:')
                            modi_phone = input('请输入新的手机号:')
                            modi_email = input('请输入新的邮箱:')
                            modi_address = input('请输入新的地址:')
                            dict_cur_perinfo.update(姓名=modi_name)
                            dict_cur_perinfo.update(手机号=modi_phone)
                            dict_cur_perinfo.update(电子邮箱=modi_email)
                            dict_cur_perinfo.update(联系地址=modi_address)
                            print(persion_info)
            elif fun_num == '5':  # 查找联系人
                query_name = input('请输入要查找的联系人姓名:')
                for i in persion_info:
                    if query_name in i.values():
                        index_num = persion_info.index(i)
                for title, info in persion_info[index_num].items():
                    print(title + ":" + info)
        else:
            print('通讯录是空的!请输入一些联系人信息!')
            continue
    elif fun_num == '6':
        print('谢谢使用!')
        break

在Python中,字典是可变对象,即对字典进行更改时,修改的是字典本身,而不是字典的副本或拷贝。在你的代码中,通过将字典赋值给一个变量dict_cur_perinfo,你实际上是将字典的引用存储在dict_cur_perinfo变量中。当你通过update()函数修改dict_cur_perinfo中的值时,实际上是在修改这个字典本身,而不是创建一个新的字典。

因此,当你在修改dict_cur_perinfo之后打印出persion_info时,你看到的是persion_info中的相应元素也已经被修改了。要避免这种情况,你可以使用字典的copy()方法创建一个字典的副本,并将其赋值给dict_cur_perinfo,如下所示:

dict_cur_perinfo = persion_info[index_num].copy()

这样,你将修改副本,而不是原始字典。

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632