每道题后都附有参考答案,对参考答案和自己写的代码都有解释和说明,有理解性的批注
# 第五章课后习题 # 1. dicTXL = {'小新':{'手机号':13913000001,'QQ':18191220001}, '小亮':{'手机号':13913000002,'QQ':18191220002}, '小刚':{'手机号':13913000003,'QQ':18191220003}} dicOther = {'大刘':{'手机号':13913400001,'QQ':18191230001}, '大王':{'手机号':13913400002,'QQ':18191230002}, '大张':{'手机号':13913400003,'QQ':18191230003}} # 将dicOther合并到dicTXL dicTXL.update(dicOther) # print(dicTXL) # {'小新': {'手机号': 13913000001, 'QQ': 18191220001}, '小亮': {'手机号': 13913000002, 'QQ': 18191220002}, # '小刚': {'手机号': 13913000003, 'QQ': 18191220003}, '大刘': {'手机号': 13913400001, 'QQ': 18191230001}, # '大王': {'手机号': 13913400002, 'QQ': 18191230002}, '大张': {'手机号': 13913400003, 'QQ': 18191230003}} # 创建dicWX dicWX = {'小新':'xx9907', '小刚':'gang1004', '大刘':'jack_w', '大王':'liu666'} # 把dicWX合并到dicTXL中,没有微信号的默认为手机号 for k,v in dicTXL.items(): # 遍历TXL dicTXL[k]['微信号'] = dicWX.get(k,dicTXL[k]['手机号']) # dicTXL[k]['微信号']相当于添加了个新的,dicWX.get(k,dicTXL[k]['手机号'])表达就是如果没有用手机号代替 print(dicTXL) # v["微信"]=dicWX.get(k,v["手机"]) # 参考答案写的 # {'小新': {'手机号': 13913000001, 'QQ': 18191220001, '微信号': 'xx9907'}, # '小亮': {'手机号': 13913000002, 'QQ': 18191220002, '微信号': 13913000002}, # '小刚': {'手机号': 13913000003, 'QQ': 18191220003, '微信号': 'gang1004'}, # '大刘': {'手机号': 13913400001, 'QQ': 18191230001, '微信号': 'jack_w'}, # '大王': {'手机号': 13913400002, 'QQ': 18191230002, '微信号': 'liu666'}, # '大张': {'手机号': 13913400003, 'QQ': 18191230003, '微信号': 13913400003}} # 仅仅只是把dicWX合并到dicTXL中 # for k,v in dicWX.items(): # dicTXL[k]['微信号'] = dicWX.get(k) # print(dicTXL) # print(dicTXL) # {'小新': {'手机号': 13913000001, 'QQ': 18191220001, # '微信号': 'xx9907'}, '小亮': {'手机号': 13913000002, 'QQ': 18191220002}, # '小刚': {'手机号': 13913000003, 'QQ': 18191220003, '微信号': 'gang1004'}, # '大刘': {'手机号': 13913400001, 'QQ': 18191230001, '微信号': 'jack_w'}, # '大王': {'手机号': 13913400002, 'QQ': 18191230002, '微信号': 'liu666'}, # '大张': {'手机号': 13913400003, 'QQ': 18191230003}} # 仅仅只是把dicWX合并到dicTXL中的等价写法 # for k,v in dicTXL.items(): # for k1,v1 in dicWX.items(): # if k == k1 : # dicTXL[k]['微信号'] = dicWX.get(k1) # break # {'小新': {'手机号': 13913000001, 'QQ': 18191220001, '微信号': 'xx9907'}, # '小亮': {'手机号': 13913000002, 'QQ': 18191220002, '微信号': 13913000002}, # '小刚': {'手机号': 13913000003, 'QQ': 18191220003, '微信号': 'gang1004'}, # '大刘': {'手机号': 13913400001, 'QQ': 18191230001, '微信号': 'jack_w'}, # '大王': {'手机号': 13913400002, 'QQ': 18191230002, '微信号': 'liu666'}, # '大张': {'手机号': 13913400003, 'QQ': 18191230003, '微信号': 13913400003}} # ①将“大王”的手机号更改为 13914000004 dicTXL['大王']['手机号'] = 13914000004 # print(dicTXL['大王']['手机号']) # 13914000004 # ②输入姓名查找对应同学的手机号、QQ号或者微信号,如果输入的姓名不存在,则返回“没有该同学的联系方式” print(dicTXL.get('大张','没有该同学的联系方式')) # name=input("请输入要查询的学生姓名:") print(dicTXL.get('大王','没有该同学的联系方式')) # print(dicTXL.get(name,"没有该同学的联系方式")) print(dicTXL.get('小李','没有该同学的联系方式')) # 应该这样写,不是手动print print(dicTXL.get('小马','没有该同学的联系方式')) print(dicTXL.get('小刚','没有该同学的联系方式')) # {'手机号': 13913400003, 'QQ': 18191230003, '微信号': 13913400003} # {'手机号': 13914000004, 'QQ': 18191230002, '微信号': 'liu666'} # 没有该同学的联系方式 # 没有该同学的联系方式 # {'手机号': 13913000003, 'QQ': 18191220003, '微信号': 'gang1004'} # 参考答案 # dicTXL={"小新":{"手机":"13913000001","QQ":"18191220001"}, # # "小亮":{"手机":"13913000002","QQ":"13913000002"}, # # "小刚":{"手机":"13913000003","QQ":"18191220003"}} # # dicOther={"大刘":{"手机":"13914000001","QQ":"18191230001"}, # # "大王":{"手机":"13914000002","QQ":"18191230002"}, # # "大张":{"手机":"13914000003","QQ":"18191230003"}} # # dicTXL.update(dicOther) # # dicWX={"小新":"xx9907","小刚":"gang1004","大王":"jack_w","大刘":"liu666"} # # for k,v in dicTXL.items(): # # v["微信"]=dicWX.get(k,v["手机"]) # # for k,v in dicTXL.items(): # # print(k,v) # # print("大王原来的通信方式") # # print(dicTXL["大王"]) # # dicTXL["大王"]["手机"]="13914000004" # # print("大王更改后的通信方式") # # print(dicTXL["大王"]) # # name=input("请输入要查询的学生姓名:") # # print(dicTXL.get(name,"没有该同学的联系方式")) # # 小新 {'手机': '13913000001', 'QQ': '18191220001', '微信': 'xx9907'} # # 小亮 {'手机': '13913000002', 'QQ': '13913000002', '微信': '13913000002'} # # 小刚 {'手机': '13913000003', 'QQ': '18191220003', '微信': 'gang1004'} # # 大刘 {'手机': '13914000001', 'QQ': '18191230001', '微信': 'liu666'} # # 大王 {'手机': '13914000002', 'QQ': '18191230002', '微信': 'jack_w'} # # 大张 {'手机': '13914000003', 'QQ': '18191230003', '微信': '13914000003'} # # 大王原来的通信方式 # # {'手机': '13914000002', 'QQ': '18191230002', '微信': 'jack_w'} # # 大王更改后的通信方式 # # {'手机': '13914000004', 'QQ': '18191230002', '微信': 'jack_w'} # # 请输入要查询的学生姓名:小刘 # # 没有该同学的联系方式 # 2. b = {'012': [90,94,97,86,85,89,88,85], '005':[91,91,92,98,90,96,90,95], '108':[96,86,97,96,87,86,86,96], '037':[95,95,94,93,97,98,99,95], '066':[95,87,94,94,93,99,96,97], '020':[89,97,91,95,89,94,97,92]} # 创建一个新字典用来放求好的最终结果 bb = {} # 遍历条目 for k,v in b.items(): # print(v) # [90, 94, 97, 86, 85, 89, 88, 85] # [91, 91, 92, 98, 90, 96, 90, 95] # [96, 86, 97, 96, 87, 86, 86, 96] # [95, 95, 94, 93, 97, 98, 99, 95] # [95, 87, 94, 94, 93, 99, 96, 97] # [89, 97, 91, 95, 89, 94, 97, 92] # 排序 v.sort() # [85, 85, 86, 88, 89, 90, 94, 97] # [90, 90, 91, 91, 92, 95, 96, 98] # [86, 86, 86, 87, 96, 96, 96, 97] # [93, 94, 95, 95, 95, 97, 98, 99] # [87, 93, 94, 94, 95, 96, 97, 99] # [89, 89, 91, 92, 94, 95, 97, 97] # 删除最小值和最大值 v.pop(0) v.pop(-1) # [85, 86, 88, 89, 90, 94] # [90, 91, 91, 92, 95, 96] # [86, 86, 87, 96, 96, 96] # [94, 95, 95, 95, 97, 98] # [93, 94, 94, 95, 96, 97] # [89, 91, 92, 94, 95, 97] # 求每个选手的平均值,并把结果放到对应的选手编号里 bb[k] = sum(v) / len(v) print(bb) # {'012': 88.66666666666667, '005': 92.5, '108': 91.16666666666667, '037': 95.66666666666667, '066': 94.83333333333333, '020': 93.0} # 下面这些注释掉的是我的尝试,因为不想删掉就给注释了 # avg.sort(reverse=True) # avg1 = sorted(avg,reverse=True) # print(avg1) # [95.66666666666667, 94.83333333333333, 93.0, 92.5, 91.16666666666667, 88.66666666666667] # 对bb这个字典按照 值 进行排序 # 首先用列表生成式把字典转化为列表,并把 键 和 值 换位置 bb1 = [(v,k) for k,v in bb.items()] print(bb1) # [(88.66666666666667, '012'), (92.5, '005'), (91.16666666666667, '108'), (95.66666666666667, '037'), (94.83333333333333, '066'), (93.0, '020')] # 对分数进行排序 bb2 = sorted(bb1,reverse=True) print(bb2) # [(95.66666666666667, '037'), (94.83333333333333, '066'), (93.0, '020'), (92.5, '005'), (91.16666666666667, '108'), (88.66666666666667, '012')] # 再把位置重新换回来,将 键 和 值 换位置 bb3 = [(k,v) for (v,k) in bb2] print(bb3) # [('037', 95.66666666666667), ('066', 94.83333333333333), ('020', 93.0), ('005', 92.5), ('108', 91.16666666666667), ('012', 88.66666666666667)] # 其实不把列表转换过来也是可以的 # 把列表重新转换回字典 bb4= dict(bb3) print(bb4) # {'037': 95.66666666666667, '066': 94.83333333333333, '020': 93.0, '005': 92.5, '108': 91.16666666666667, '012': 88.66666666666667} # 最后按照由高到低,一个一个输出选手编号和最终成绩 for k,v in bb4.items(): print('{:<4}:{:>6.2f}'.format(k,v)) # 037 : 95.67 # 066 : 94.83 # 020 : 93.00 # 005 : 92.50 # 108 : 91.17 # 012 : 88.67 # 参考答案 scores={"012":[90,94,97,86,85,89,88,85], "005":[91,91,92,98,90,96,90,95], "108":[96,86,97,96,87,86,86,96], "037":[95,95,94,93,97,98,99,95], "066":[95,87,94,94,93,99,96,97], "020":[89,97,91,95,89,94,97,92]} # 参考答案写的更好 for v in scores.values(): # 遍历 值,不是像我那样遍历了条目 v.remove(max(v)) # 这里直接找到最大最小值并去除 v.remove(min(v)) print(scores) # {'012': [90, 94, 86, 89, 88, 85], '005': [91, 91, 92, 96, 90, 95], '108': [96, 96, 87, 86, 86, 96], '037': [95, 95, 94, 97, 98, 95], '066': [95, 94, 94, 93, 96, 97], '020': [91, 95, 89, 94, 97, 92]} avg={ } # 创建了新字典用于放求出的平均数 for k,v in scores.items(): # 这里对原条目进行遍历 avg[k]=(round(sum(v)/len(v),2)) # round() 是内置函数,四舍五入,2是保留两位小数 # 给新字典添加条目,写法简单简洁 # 想通过给 值 也就是最后的平均分排序,需要 用到的方法是 前面例题讲过的 # 1.用列表生成式将 键 和 值 转换,生成一个新列表 # 2.然后用sort方法排序 # 3.最后再用一次列表生成式把 键 和 值 在换回来 results=[(v,k) for k,v in avg.items()] results.sort(reverse=True) results=[(k,v) for v,k in results] print(results) # [('037', 95.67), ('066', 94.83), ('020', 93.0), ('005', 92.5), ('108', 91.17), ('012', 88.67)] # 3. # 我这个创建集合的方式麻烦了,我是先创建了个空集合,再写的元素 # 当时写的时候忘了其实可以直接创建 # 所以下面我给注释掉了 # t1 = set() # t2 = set() # t3 = set() t1 = {'李雷','张玉','王晓刚','陈红静','方向','司马清'} t2 = {'施然','李芳芳','刘潇','方向','孙一航','黄煌'} t3 = {'陈红静','方向','刘培良','张玉','施小冉','司马清'} t1.update(t2) # 我这里写的太麻烦了,下面的参考答案更直接简单 t1.update(t3) # 我是把其他两个用update()方法去重加到第一个里面 # print(t1) # 但是这样写很不推荐因为这样改变了t1,如果不注意还认为t1没有改变,就会出错,这样写也导致了我后面求的都是错的,忽略了t1已经改变 # 所以后来再纠正的时候,为了微小改动,不改变update的做法(提醒自己),就重新添加了t11作为t1 # {'李雷', '司马清', '施小冉', '黄煌', '陈红静', '方向', '刘潇', '孙一航', '李芳芳', '王晓刚', '张玉', '刘培良', '施然'} # ①这个班有多少位学生没有选课? print('这个班有{}位学生没有选课'.format(25-len(t1))) # 这个班有12位学生没有选课 t11 = {'李雷','张玉','王晓刚','陈红静','方向','司马清'} # 我是通过集合间的运算来求解的 # 下面的参考答案给的给了两种方法,第二种与我的一样 # ②有多少位学生同时选修了 2 门课? # 求两个课程的交集 a1 = t11 & t2 a2 = t11 & t3 a3 = t2 & t3 print(a1,a2,a3) # {'方向'} {'司马清', '方向', '陈红静', '张玉'} {'方向'} aa = (a2 | a1 |a3) - (t2 & t3 & t11) # 要注意最后要减去三个集合的交集,即同时选修了三门课程 # print(aa) # {'司马清', '陈红静', '张玉'} # 上写的一堆与下面的一条代码是等价的 z1 = ((t11 & t2) | (t11 & t3) | (t2 & t3)) - (t2 & t3 & t11) # print(z1) # print(z1 == aa) # True print('有{}位学生同时选修了2门课'.format(len(aa))) # 有3位学生同时选修了2门课 # ③有多少位学生同时选修了 3 门课? # 求三门课程的交集 b = t11 & t2 & t3 print(b) print('有{}位学生同时选修了3门课'.format(len(b))) # 有1位学生同时选修了3门课 # ④有多少位学生只选修了1门课? # 下面一大块是错的,不用看直接跳过 # 留着是为了提醒自己这样写不对 # c1 = t3 ^ t2 # c2 = t3 ^ t11 # c3 = t2 ^ t11 # print(c2,c3,c1) # # {'施小冉', '王晓刚', '李雷', '刘培良'} # # {'刘潇', '张玉', '司马清', '施然', '李芳芳', '陈红静', '李雷', '孙一航', '黄煌', '王晓刚'} # # {'刘潇', '张玉', '司马清', '施然', '李芳芳', '陈红静', '孙一航', '黄煌', '施小冉', '刘培良'} # # # d1 = c1 & c3 # d2 = c3 & c2 # d3 = c1 & c2 # print(d1,d2,d3) # # {'施然', '李芳芳', '刘潇', '陈红静', '张玉', '孙一航', '黄煌', '司马清'} # # {'李雷', '王晓刚'} # # {'施小冉', '刘培良'} # # # d = (c3 + c2 | c1) - (d1 | d2 | d3) - (d1 | d2 | d3) # print(d) # # {'施然', '李芳芳', '刘潇', '陈红静', '张玉', '李雷', '孙一航', '黄煌', '施小冉', '王晓刚', '刘培良', '司马清'} c = (t3 ^ t2 ^ t11) - (t11 & t2 & t3) # print(c) # {'孙一航', '施然', '施小冉', '黄煌', '刘潇', '李芳芳', '李雷', '王晓刚', '刘培良'} print('有{}位学生只选修了1门课'.format(len(c))) # 有9位学生只选修了1门课 # 参考答案 # set1 = {'李雷','张玉','王晓刚','陈红静','方向','司马清'} # # set2 = {'施然','李芳芳','刘潇','方向','孙一航','黄煌'} # # set3 = {'陈红静','方向','刘培良','张玉','施小冉','司马清'} # # # # ①这个班有多少位学生没有选课? # # print(25-len(set1|set2|set3)) # 这里直接求并集,并集里面就包含去重了,直接简洁 # # 12 # # # ②有多少位学生同时选修了2门课? # # list_2 = list(set1) + list(set2) + list(set3) # # # # 这个方法是把这三个集合转换为列表 # # 想用列表求元素出现次数的方法求解 # # # 我认为求解②,用这种方法思路上比方法二更简单,因为方法二容易忘记 最后要把 同时选修了三门课程的人给除去 # # count2 = set() # 设置一个空集合,用来存放同时选修两门课程的人名 # # for i in list_2: # # if list_2.count(i)==2: # # count2.add(i) # # # # print(len(count2)) # # print(count2) # # # # # 方法二 # # # select2 = ((set1 & set2)|(set1 & set3)|(set2 & set3))-(set1 & set2 & set3) # # # print(select2) # # # print('有',len(select2),'位学生同时选修了2门课。') # # 3 # # {'陈红静', '张玉', '司马清'} # # # ③有多少位学生同时选修了3门课? # # list_3 = list(set1) + list(set2) + list(set3) # # # # 这个方法是把这三个集合转换为列表 # # 想用列表求元素出现次数的方法求解 # # # count3 = set() # # for i in list_3: # # if list_3.count(i)==3: # # count3.add(i) # # # # print(len(count3)) # # print(count3) # # # # 我认为求解③,用这种方法上比方法一更简单,因为方法一写得多,思路上方法二也更简单 # # # # 方法二 # # # select3 = set1 & set2 & set3 # # # print(select3) # # # print('有',len(select3),'位学生同时选修了3门课。') # # 1 # # {'方向'} # # # # # ④有多少位学生只选修了1门课? # # list_1 = list(set1) + list(set2) + list(set3) # # # # count1 = set() # # for i in list_1: # # if list_1.count(i)==1: # # count1.add(i) # # # # print(len(count1)) # # print(count1) # # # # # 方法二 # # # select1 = (set1^set2^set3)-(set1&set2&set3) # # # print(select1) # # # print('有',len(select1),'位学生只选修了1门课。') # # 9 # # {'刘潇', '施小冉', '孙一航', '黄煌', '李芳芳', '施然', '李雷', '刘培良', '王晓刚'} # # # # 从②③④来看,若用方法一,可以不用考虑这么多,②③④直接通用