合并购物清单

1. 实战目标

data目录下有两份购物清单,内容格式如下

黄瓜 1斤
西红柿 1.5斤
猪肉 2斤
羊肉 1.5斤
茄子 3斤
土豆 2斤

两份清单有重叠的部分,现在请实现函数merge_shopping_lst,合并两份购物清单,写入文件merge.txt, 两份清单中重复项保留重量较多的

def merge_shopping_lst(shopping_list_file_1, shopping_list_file_2):
    """
    合并两张购物清单
    :param shopping_list_file_1: 清单1
    :param shopping_list_file_2: 清单2
    :return:
    """

2. 考察知识点

  1. 字典的使用
  2. 文件读写
  3. 字符串切分
  4. 列表切片
  5. 类型转换
  6. f-string

3. 思路讲解与实现

3.1 用字典保存购物信息

用清单上的物品做key, 斤数做value来保存购物清单信息,两个个购物清单用两个字典来保存,合并的过程就是将两个字典合并为一个字典

def read_shopping_lst(shopping_list_file):
    shopping_info = {}
    with open(shopping_list_file, encoding="utf-8")as f:
        for line in f:
            line = line.strip()
            name, weight = line.split(" ")
            weight = float(weight[:-1])
            shopping_info[name] = weight

    return shopping_info

函数read_shopping_lst 读取一份购物清单文件,注意打开时设置encoding参数为utf-8, f是打开的文件对象,是可迭代对象,使用for循环可以逐行遍历文件里的内容,strip方法可以去掉字符串前后的换行,回车,空格等特殊字符。

购物项和重量之间是空格,使用split方法以空格做分隔符切分字符串,重量这块咱们得把斤这个字给去掉,那么使用切片就很方便了,使用float函数将字符串转为float类型数据,做这个转换是为了比较两份清单里相同的购物项哪个清单里的购买量更多。

最后用name做key, 用weight 做value。

3.2 合并字典

def merge_shopping_lst(shopping_list_file_1, shopping_list_file_2):
    """
    合并两张购物清单
    :param shopping_list_file_1: 清单1
    :param shopping_list_file_2: 清单2
    :return:
    """
    shopping_info_1 = read_shopping_lst(shopping_list_file_1)
    shopping_info_2 = read_shopping_lst(shopping_list_file_2)
    for key, value in shopping_info_2.items():
        if key not in shopping_info_1:
            shopping_info_1[key] = value
        elif value > shopping_info_1[key]:
            shopping_info_1[key] = value

    with open("./data/merge.txt", 'w', encoding="utf-8")as f:
        for key, value in shopping_info_1.items():
            f.write(f"{key} {round(value, 1)}斤\n")
  • 遍历shopping_info_2,判断它的key是否在shopping_info_1 中
  • 如果不在,则说明这个购物项只在清单2中,将key和value加入到shopping_info_1中
  • 如果在,那么就比较哪个value更大,如果shopping_info_2里的这一项的value更大,就更新shopping_info_1

最后打开merge.txt 文件,遍历shopping_info_1字典,使用f-string语法初始化字符串并写入到文件中,由于value都是float类型数据,为了只保留一位小数,使用round函数对value数值做一次转化。

4. 完整代码

def merge_shopping_lst(shopping_list_file_1, shopping_list_file_2):
    """
    合并两张购物清单
    :param shopping_list_file_1: 清单1
    :param shopping_list_file_2: 清单2
    :return:
    """
    shopping_info_1 = read_shopping_lst(shopping_list_file_1)
    shopping_info_2 = read_shopping_lst(shopping_list_file_2)
    for key, value in shopping_info_2.items():
        if key not in shopping_info_1:
            shopping_info_1[key] = value
        elif value > shopping_info_1[key]:
            shopping_info_1[key] = value

    with open("./data/merge.txt", 'w', encoding="utf-8")as f:
        for key, value in shopping_info_1.items():
            f.write(f"{key} {round(value, 1)}斤\n")


def read_shopping_lst(shopping_list_file):
    shopping_info = {}
    with open(shopping_list_file, encoding="utf-8")as f:
        for line in f:
            line = line.strip()
            name, weight = line.split(" ")
            weight = float(weight[:-1])
            shopping_info[name] = weight

    return shopping_info


if __name__ == "__main__":
    merge_shopping_lst("./data/购物清单1.txt", "./data/购物清单2.txt")

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案