Python.第五章课后题

每道题后都附有参考答案,对参考答案和自己写的代码都有解释和说明,有理解性的批注 

# 第五章课后习题

# 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
#
# {'刘潇', '施小冉', '孙一航', '黄煌', '李芳芳', '施然', '李雷', '刘培良', '王晓刚'}
#
#
# # 从②③④来看,若用方法一,可以不用考虑这么多,②③④直接通用
  • 33
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值