Python 避免字典和元组的多重嵌套问题


Posted in Python onJuly 15, 2022

一、字典、元组的多重嵌套

例 1:记录全班学生的成绩。

分析:定义一个 SimpleGradebook类,

学生名是字典self._grades的键,成绩是字典self._grades的值。

class SimpleGradebook():
    def __init__(self):
        self._grades = {}
    def add_student(self, name):
        self._grades[name] = []
    def report_grade(self, name, score):
        self._grades[name].append(score)
    def average_grade(self, name):
        grades = self._grades[name]
        return self._grades, sum(grades) / len(grades)
book = SimpleGradebook()
book.add_student('qinlu')
book.report_grade('qinlu', 99)
print(book.average_grade('qinlu'))
({'qinlu': [99]}, 99.0)

字典可能因为功能过多导致结果多重嵌套。

例 2:扩充 SimpleGradebook类,按科目保存成绩。

分析:定义一个 BySubjectGradebook类,字典by_subject嵌套在字典self._grades内。

学生名是字典self._grades的键,科目、成绩是self._grades的值。

科目是字典by_subject的键,成绩是字典by_subject的值。

class BySubjectGradebook():
    """
        report_grade(), average_grade()嵌套了两层的字典
    """
    def __init__(self):
        self._grades = {}
    def add_student(self, name):
        self._grades[name] = {}
    def report_grade(self, name, subject, score):
        by_subject = self._grades[name]
        grade_list = by_subject.setdefault(subject, [])
        grade_list.append(score)
    def average_grade(self, name):
        by_subject = self._grades[name]
        total, count = 0, 0
        for scores in by_subject.values():
            total += sum(scores)
            count += len(scores)
        return self._grades, total / count
book = BySubjectGradebook()
book.add_student('qinlu')
book.report_grade('qinlu', 'Math', 99)
book.report_grade('qinlu', 'Math', 88)
book.report_grade('qinlu', 'Computer', 90)
book.report_grade('qinlu', 'Computer', 80)
print(book.average_grade('qinlu'))
({'qinlu': {'Math': [99, 88], 'Computer': [90, 80]}}, 89.25)

例 3:需求变更,需记录每次成绩占总成绩的权重。(期中、期末考试所占的分量比随堂考大)

class WeightedGradebook():
    def __init__(self):
        self._grades = {}
    def add_student(self, name):
        self._grades[name] = {}
    def report_grade(self, name, subject, score, weight):
        by_subject = self._grades[name]
        grade_list = by_subject.setdefault(subject, [])
        grade_list.append(score, weight)
    def average_grade(self, name):
        by_subject = self._grades[name]
        score_sum, score_count = 0, 0
        for subject, scores in by_subject.items():
            subject_avg, total_weight = 0, 0
            for score, weight in scores:
                #...
        return score_sum / score_count

该代码出现字典、元组的多层嵌套,应拆解为类。多层嵌套的代码,很难维护。

二、嵌套结构重构为类

将下面的字典重构为类。

字典by_subject嵌套在字典self._students内。

{'qinlu': {'Math': [(99, 0.1), (88, 0.9)], 'Computer': [(90. 0.1), (80, 0.9)]}}

分析:

① Gradebook()类,学生名是字典self._students的键;科目、成绩、权重是self._grades的值。

② Student()类,科目是字典self._subjects的键;成绩、权重是self._subjects的值。

③ Subject()类,成绩是列表self._grades的第一位;权重是列表self._grades的第二位。

从最底层开始重构,即考试成绩。这么简单的信息,没必要写成类。

namedtuple()命名元组。

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流群:711312441
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
from collections import namedtuple

Grade = namedtuple('Grade', ('score', 'weight'))

# 科目类,该类包含考试成绩
class Subject():
    def __init__(self):
        self._grades = []
    def report_grade(self, score, weight):
        self._grades.append(Grade(score, weight))
    def average_grade(self):
        total, total_weight = 0, 0
        # print(self._grades)
        for grade in self._grades:
            # print(grade)
            total += grade.score * grade.weight
            total_weight += grade.weight
        return total / total_weight

# 学生类,该类包含学习课程
class Student():
    def __init__(self):
        self._subjects = {}
    def subject(self, name):
        if name not in self._subjects:
            self._subjects[name] = Subject()
        return self._subjects[name]
    def average_grade(self):
        total, count = 0, 0
        for subject in self._subjects.values():
            total += subject.average_grade()
            count += 1
        return total / count

# 成绩册类,包含所有学生考试成绩的容器类,该容器类以学生名字为键,可动态添加学生
class Gradebook():
    def __init__(self):
        self._students = {}
    def student(self, name):
        if name not in self._students:
            self._students[name] = Student()
        return self._students[name]

book = Gradebook()
qin = book.student('qinlu')
math = qin.subject('Math')
math.report_grade(99, 0.1)
math.report_grade(88, 0.9)
print(qin.average_grade())
89.1

虽然代码量是原来的两倍,但更清晰,更易扩展,理解起来比原来容易。

到此这篇关于Python 避免字典和元组的多重嵌套的文章就介绍到这了,更多相关Python 多重嵌套内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python遍历zip文件输出名称时出现乱码问题的解决方法
Apr 08 Python
Python 装饰器使用详解
Jul 29 Python
python导入csv文件出现SyntaxError问题分析
Dec 15 Python
Python Xml文件添加字节属性的方法
Mar 31 Python
python基于C/S模式实现聊天室功能
Jan 09 Python
python实现烟花小程序
Jan 30 Python
在python中做正态性检验示例
Dec 09 Python
Python 实现OpenCV格式和PIL.Image格式互转
Jan 09 Python
详解Python中namedtuple的使用
Apr 27 Python
python 如何快速复制序列
Sep 07 Python
python语言实现贪吃蛇游戏
Nov 13 Python
只需要100行Python代码就可以实现的贪吃蛇小游戏
May 27 Python
Pytorch中expand()的使用(扩展某个维度)
Jul 15 #Python
Python实现聚类K-means算法详解
Jul 15 #Python
python自动获取微信公众号最新文章的实现代码
Jul 15 #Python
pytorch实现加载保存查看checkpoint文件
Jul 15 #Python
pytest实现多进程与多线程运行超好用的插件
Jul 15 #Python
python如何将mat文件转为png
Jul 15 #Python
python读取mat文件生成h5文件的实现
Jul 15 #Python
You might like
php xml常用函数的集合(比较详细)
2013/06/06 PHP
ThinkPHP的cookie和session冲突造成Cookie不能使用的解决方法
2014/07/01 PHP
Prototype PeriodicalExecuter对象 学习
2009/07/19 Javascript
JS判断移动端访问设备并加载对应CSS样式
2014/06/13 Javascript
nodejs开发环境配置与使用
2014/11/17 NodeJs
jQuery实现的经典竖向伸缩菜单效果代码
2015/09/24 Javascript
jQuery的promise与deferred对象在异步回调中的作用
2016/05/03 Javascript
老生常谈JavaScript中的this关键字
2016/10/01 Javascript
移动端日期插件Mobiscroll.js使用详解
2016/12/19 Javascript
详解VueJs前后端分离跨域问题
2017/05/24 Javascript
JS 设置Cookie 有效期 检测cookie
2017/06/15 Javascript
解析Vue.js中的组件
2018/02/02 Javascript
基于Bootstrap下拉框插件bootstrap-select使用方法详解
2018/08/07 Javascript
JavaScript的Proxy可以做哪些有意思的事儿
2019/06/15 Javascript
JS实现动态倒计时功能(天数、时、分、秒)
2019/12/12 Javascript
[56:12]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第一场 6.3
2018/06/04 DOTA
Python实现保证只能运行一个脚本实例
2015/06/24 Python
用Python的Flask框架结合MySQL写一个内存监控程序
2015/11/07 Python
Python实现的根据文件名查找数据文件功能示例
2018/05/02 Python
对python-3-print重定向输出的几种方法总结
2018/05/11 Python
Python里字典的基本用法(包括嵌套字典)
2019/02/27 Python
python3.7 使用pymssql往sqlserver插入数据的方法
2019/07/08 Python
python代码打印100-999之间的回文数示例
2019/11/24 Python
python通过文本在一个图中画多条线的实例
2020/02/21 Python
matplotlib.pyplot.matshow 矩阵可视化实例
2020/06/16 Python
css3实现的下拉菜单效果示例
2014/01/22 HTML / CSS
世界闻名的衬衫制造商:Savile Row Company
2018/07/30 全球购物
英国川宁茶官方网站:Twinings茶
2019/05/21 全球购物
企业治理工作自我评价
2013/09/26 职场文书
校长先进事迹材料
2014/02/01 职场文书
护士年终考核评语
2014/12/31 职场文书
教导主任个人总结
2015/03/03 职场文书
人事任命通知
2015/04/20 职场文书
《鲁班学艺》读后感3篇
2019/11/27 职场文书
Python 中数组和数字相乘时的注意事项说明
2021/05/10 Python
Python字符串的转义字符
2022/04/07 Python