1 题目分析与思路描述

1.1 题目描述

用字典+列表 实现以下通讯录的增删改查功能:
题目

1.2 分析与思路

1.2.1 增

首先,我们可以用字典来储存每一位联系人的信息:姓名作为联系人的键,手机号、邮箱、地址作为联系人这个键的值。
那么,用什么来储存这些联系人的字典呢?由于元组与集合的元素不能被修改,而本题通讯录中的联系人信息是要实现“增删改查”的,因此最佳的选择当然是使用列表。
所以,我们来创建这两个容器:

list = {}
dict1 = {}, dict2 = {}, dict3 = {},# 此处省略无数个联系人信息构成的字典,之后我们在完整代码中通过循环来实现。

容器创建好了,但是里面没有内容啊,怎么能说是通讯录呢?因此,我们需要“增”!实现第一个功能:添加联系人!
我们要增加什么呢?当然是联系人以及其对应的信息:第一是新增一个字典并在这个字典里增加联系人的信息,第二是将这个字典增加到列表中。前者使用字典的增加方法update()来新增一个字典并用字典名[键]=值的方式来添加这个新增字典里的条目,后者使用列表的增加方法append()增加字典这个元素。

name=input("请输入联系人的姓名:")
phone=input("请输入联系人的手机号:")
email=input("请输入联系人的邮箱:")
address=input("请输入联系人的地址:")

dict.update({"姓名": name, "手机号": phone, "电子邮箱": email, ",联系地址": address})

list.append(dict)

于是,我们的通讯录中就有了第一个联系人,通过循环我们可以再生出无数个联系人,正如两千年前的先哲老子所言一生二,二生三,三生万物

将该功能写成函数如下:

def add(name, phone, email, address):
    dict.update({"姓名": name,
                   "手机号": phone,
                   "电子邮箱": email,
                   "联系地址": address})
    list.append(dict)

1.2.2 查

好的,那么当我们有了很多个联系人的时候,我们应该怎么知道这个通讯录中联系人有哪些以及对应的信息呢?于是我们第二个功能的需求就出来了,那就是“查”!
查什么?根据题意,一是用户可以通过遍历查看这个通讯录所有的联系人以及信息(功能2),二是用户可以输入某个联系人的姓名查看其对应的信息。(功能5)
先来实现前者(功能2),我们可以用for循环遍历整个通讯录列表里的元素字典再用for循环遍历items()的方法来获取字典中的键和值

for i in list:
	for k, v in i.items() # k, v分别表示获取联系人的姓名(键)以及联系人的信息
	print(k + ':' + v)

再来实现后者(功能5):与功能2类似,直接如法炮制。

for i in list:
     if name in i.values():
         for k, v in i.items():
             print(k + ':' + v)

将上述写成函数,如下:

def travese():
    print("您当前的通讯录所有联系人及其对应信息为:")
    for i in list:
        for k, v in i.items():
            print(k + ' ' + v)
def search(name):
    for i in list:
        if name in i.values():
            for k, v in i.items():
                print('您要查找的联系人' + k + '的信息为:' + v)

1.2.3 删

在输入联系人的过程中,一定有不小心输错信息的时候或者也会存在有些联系人在创建之后没有再存在通讯录必要的情况,这个时候我们首先想到的是删掉这个联系人及其信息。对应在程序里删除的是通讯录列表里的一个字典元素。
我们来一起复习一下,列表删除元素的方式有哪些呢?列举如下:del命令pop()方法remove()方法。那么我们应该用哪一个呢?以下给出分析:

  1. del 列表名[索引]可以通过正向索引和反向索引的方式删掉对应的列表元素。如果我们需要使用它,就要先用index()方法找到对应的索引号。del指令

  2. 列表名.pop(索引),如果我们需要使用它,也要先用index()方法找到对应的索引号。pop()方法

  3. 列表.remove(元素值),可以直接通过输入的值删除,较为简单。remove()方法

    综上所述,我们选用方便使用的remove()方法。
    使用remove()方法删除通讯录的联系人
    如上述代码所示,我们可以通过i来遍历通讯录的列表:如果要删除的联系人的姓名是列表中某一个字典的值,那么整个条目就会被移除。

将上述结合题目要求写成函数,如下:

def delete(name):
    for i in list:
        if name in i.values():
            list.remove(i)

1.2.4 改

结合上述,如果在输入联系人的过程中,我们不小心输错了联系人的信息或者联系人的信息有所变化 ,可以使用删除这个联系人再重新增加这个联系人的方式实现。但是,这种方式过于繁琐了。
因此,我们能不能直接修改呢?以下是本人对字典更新方式的简述:

在字典创建之后通过字典名[键]=值的方法进行更新,如果在字典中键不存在就会执行添加条目操作,如果键存在就会执行修改条目操作。

于是,我们可以用以下的方式来修改字典中的值:
修改通讯录中联系人信息
如同上述的“删”使用的方法一样,我们也是用i来遍历通讯录的列表。随后,找到需要修改的联系人,并逐一给其中的每一个键赋上对应的值作为该联系人的信息。

将上述结合题目要求写成函数,如下:

def modify(name, phone, email, address):
    for i in list:
        if name in i.values():
            i.update(
                {"姓名": name,
                 "手机号": "phone",
                 "电子邮箱": email,
                 "联系地址": address})

1.2.5 注意事项

  1. 新增联系人时需要判断用户输入的信息是否不为空,如果用户输入的字符串为空' '那么需要提醒用户重新输入。对于用户输入中产生的空格我们会用到strip()方法移除,以下做出简单的解释:

    在3.12版本的Python官方文档中是这样解释的:

    strip()方法的使用

    也就是说,strip()方法括号中的内容为空就会移除字符串空白符。

  2. 查询、修改、删除联系人时需要判断原通讯录是否不为空以及该联系人是否在原通讯录中。

    1. 可以使用len()函数判断通讯录是否为空:如果为该列表长度为0则表明没有元素,提醒用户该通讯录没有信息。
    2. 可以使用in运算符判断该联系人是否存在于通讯录:用i来遍历通讯录的列表,再使用values()方法来获取对应的值,判断姓名是否存在。
  3. 在修改通讯录联系人信息的时候,可以先将该联系人信息打印出来,以方便用户修改。

  4. 如果用户输入了不在功能内的其它字符也需要有对应的提示。

2 完整代码实现

结合1.2.5的注意事项,我们将上面实现的函数进行过了修改与补充。

10月29日修改:将之前的代码修改为了使用函数的版本。

# 先假设一个通讯录,方便接下来写的时候参照:
# list = [{'姓名': '张三', '手机号': '123', '电子邮箱': '123@qq.com', '地址': '武汉'},
#         {'姓名': '李四', '手机号': '456', '电子邮箱': '456@qq.com', '地址': '武汉'}]

list = []
dict = {}

def add(name, phone, email, address):
    dict.update({"姓名": name,
                   "手机号": phone,
                   "电子邮箱": email,
                   "联系地址": address})
    list.append(dict)

def search(name):
    for i in list:
        if name in i.values():
            for k, v in i.items():
                print('您要查找的联系人' + k + '的信息为:' + v)
        else:
            print("您要查找的联系人不存在")

def travese():
    print("您当前的通讯录所有联系人及其对应信息为:")
    for i in list:
        for k, v in i.items():
            print(k + ' ' + v)

def delete(name):
    for i in list:
        if name in i.values():
            list.remove(i)
            print("删除成功")
        else:
            print("您要删除的联系人不存在")

def modify(name, phone, email, address):
    for i in list:
        # if name in i.values():
        i.update(
           {"姓名": name,
            "手机号": "phone",
            "电子邮箱": email,
            "联系地址": address})
        # else:
        #     print("您要修改的联系人不存在")

while 1:
    print("欢迎使用通讯录:")
    print("1.添加联系人")
    print("2.查看通讯录")
    print("3.删除联系人")
    print("4.修改联系人信息")
    print("5.查找联系人")
    print("6.退出")
    print("="*20)
    fun = input('请输入功能序号:')
    if fun == '1':
        print("您要实现的是添加联系人功能")
        name = input("请输入联系人的姓名:")
        phone = input("请输入联系人的手机号:")
        email = input("请输入联系人的邮箱:")
        address = input("请输入联系人的地址:")
        if(name.strip() == ' ' or phone.strip() == ' ' or email.strip() == ' ' or address.strip() == ' '):
            print("输入有误,请重新输入")
        else:
            add(name, phone, email, address)
            print("添加成功")
    elif fun == '2':
        print("您要实现的是查看通讯录功能")
        if len(list) == 0:
            print("您当前的通讯录为空")
        else:
            travese()
    elif fun == '3':
        print("您要实现的是删除联系人功能")
        if len(list) == 0:
            print("您当前的通讯录为空")
        else:
            name = input("请输入要删除的联系人姓名:")
            delete(name)
    elif fun == '4':
        print("您要实现的是修改联系人信息功能")
        if(len(list) == 0):
            print("您当前的通讯录为空")
        else:
            name = input("请输入要修改的联系人姓名:")
            for i in list:
                if name in i.values():
                    for k, v in i.items():
                        print(k+':'+v)
                    phone = input("请输入新的联系人手机号:")
                    email = input("请输入新的联系人邮箱:")
                    address = input("请输入新的联系人地址:")
                    modify(name, phone, email, address)
                else:
                    print("您要修改的联系人不存在")
    elif fun == '5':
        print("您要实现的是查找联系人功能:")
        name = input("请输入您要查找的联系人姓名:")
        search(name)
    elif fun == '6':
        print("您已退出通讯录")
        break
    else:
        print("输入有误,请重新输入")

3 总结与复盘

首先,不要害怕写程序,不要害怕犯错。代码并不是人生,错了无数次就有无数次的报错提示,就有无数次不断调试和修改的机会!不断试错,在错误中学习和成长。

其次,在写程序的时候,那些无关紧要的细枝末节可以先不必考虑。放在首位思考的应是该题大致应该如何解决以及运用哪些知识点。实现了主要功能之后再去考虑在使用可能出现的问题与情况,或者在代码运行的过程中通过报错进行修改与调试。

最后,悟已往之不谏,知来者之可追。让我们跳转至下个链接,一起开启新的刷题吧!《剑指offer》该书上习题刷题记录