作业4: Python文件读取与字典


本周我们将练习数据处理中两项重要的技能:从文本文件读取数据,以及将数据存储到字典中。这将为你的下一个作业提供很好的练习☺。我们将从字典的复习开始,然后用嵌套字典来表示更复杂的信息。

📚 字典复习

你可以在Python解释器中练习以下常见的字典操作。假设我们有一个字典classes,键是课程名(字符串),值是该课程的学分数(整数)。

>>> classes = {'CS106A': 5, 'PSYCH1': 5, 'PWR1': 4}

请编写一行代码来完成以下操作:


🛒 购物清单字典

在这个问题中,你将把杂乱的购物清单整理成有用的字典结构。

你的数据

在一周内,你会随手记下要买的食材、购买地点和数量。不幸的是,你每次都把新项目记在清单底部,而不是检查是否已存在并累计数量。到购物时,你的清单可能如下:

沃尔玛:鸡蛋,1
家乐福:牛角面包,12
沃尔玛:椰奶,3
大润发:糖饼干,1
沃尔玛:面粉,1
沃尔玛:鸡蛋,2
永辉:菠萝,4
永辉:葡萄,1
家乐福:咖啡,2
永辉:羽衣甘蓝,1

你怎么知道在沃尔玛要买多少个鸡蛋?如果手动统计每个重复项会很麻烦。我们要写一个程序来帮你完成这项工作。

groceries字典

我们希望构建一个名为groceries的字典,方便查看每家商店需要购买的物品。对于上面的例子,字典结构如下:

groceries = {
    '沃尔玛': {'鸡蛋': 3, '椰奶': 3, '面粉': 1},
    '家乐福': {'牛角面包': 12, '咖啡': 2},
    '大润发': {'糖饼干': 1},
    '永辉': {'菠萝': 4, '葡萄': 1, '羽衣甘蓝': 1}
}

现在数据结构清晰了,你可以很容易地看到在沃尔玛需要买3盒鸡蛋。
我们的groceries字典以商店名为键,值为内部字典。每家商店的内部字典以商品名为键,数量为值。


🌱 热身:字典的遍历与添加

假设我们已经读入了前三行,字典如下:

groceries = {
  '沃尔玛': {'鸡蛋': 1, '椰奶': 3}, 
  '家乐福': {'牛角面包': 12}
}

如果再读入以下三行,字典会变成什么样?(建议你手写一遍!)

大润发:糖饼干,1
沃尔玛:面粉,1
沃尔玛:鸡蛋,2

➕ 添加物品

现在你已经了解了如何向groceries添加单个物品,让我们用Python实现这个过程。请编写函数add_item(groceries, store, item, num),它接收一个如上所示的groceries字典,并根据参数storeitemnum添加新物品。


🛠️ 构建购物字典

接下来,你将从文本文件中读取整个购物清单,构建groceries字典。请实现函数make_groceries(filename),在文件读取循环中调用你的add_item()辅助函数,最终返回groceries


🚀 运行你的程序

你已经完成了!现在你的程序可以把杂乱的购物清单变成有用的字典啦!
在终端运行groceries.py,并传入一个文本文件名作为参数:

$ python3 groceries.py long_list.txt
你需要从沃尔玛购买 3 个鸡蛋
你需要从沃尔玛购买 3 盒椰奶
你需要从沃尔玛购买 1 袋面粉
你需要从家乐福购买 12 个牛角面包
你需要从家乐福购买 2 包咖啡
你需要从大润发购买 1 包糖饼干
你需要从永辉购买 4 个菠萝
你需要从永辉购买 1 串葡萄
你需要从永辉购买 1 把羽衣甘蓝

🔢 最小唯一正整数

smallest_int.py文件中,实现函数find_smallest_int(filename),它接收一个文件名(字符串),该文件每行包含一个整数,返回文件中最小的唯一正整数。
正整数指大于0的整数,唯一指在文件中只出现一次。例如,假设numbers1.txt内容如下:

42
1
13
12
1
-8
20

调用find_smallest_int('numbers1.txt')应返回12。你可以假设每行只有一个整数(可能不是正数),且至少有一个正整数。
你可以用如下命令测试:

python3 smallest_int.py numbers1.txt

你还可以用numbers2.txt测试,结果应为7。