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基础教程之简单入门说明(变量和控制语言使用方法)
Mar 25 Python
使用python解析xml成对应的html示例分享
Apr 02 Python
python输出当前目录下index.html文件路径的方法
Apr 28 Python
Python入门学习之字符串与比较运算符
Oct 12 Python
利用python画一颗心的方法示例
Jan 31 Python
python实现图书管理系统
Mar 12 Python
Python去除、替换字符串空格的处理方法
Apr 01 Python
取numpy数组的某几行某几列方法
Apr 03 Python
Sanic框架蓝图用法实例分析
Jul 17 Python
Python打包方法Pyinstaller的使用
Oct 09 Python
ubuntu 18.04搭建python环境(pycharm+anaconda)
Jun 14 Python
Pytorch 图像变换函数集合小结
Feb 01 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
不用数据库的多用户文件自由上传投票系统(3)
2006/10/09 PHP
浅谈php扩展imagick
2014/06/02 PHP
CI(CodeIgniter)框架介绍
2014/06/09 PHP
javascript Array.sort() 跨浏览器下需要考虑的问题
2009/12/07 Javascript
js 实现无干扰阴影效果 简单好用(附文件下载)
2009/12/27 Javascript
在chrome中window.onload事件的一些问题
2010/03/01 Javascript
javaScript中slice函数用法实例分析
2015/06/08 Javascript
使用jQuery在对象中缓存选择器的简单方法
2015/06/30 Javascript
JavaScript中的Function函数
2015/08/27 Javascript
jQuery层次选择器用法示例
2016/09/09 Javascript
Axios学习笔记之使用方法教程
2017/07/21 Javascript
weex slider实现滑动底部导航功能
2017/08/28 Javascript
Vue-router 类似Vuex实现组件化开发的示例
2017/09/15 Javascript
Three.js利用dat.GUI如何简化试验流程详解
2017/09/26 Javascript
JavaScript表格隔行变色和Tab标签页特效示例【附jQuery版】
2019/07/11 jQuery
Flexible.js可伸缩布局实现方法详解
2020/11/13 Javascript
[38:32]DOTA2上海特级锦标赛A组资格赛#2 Secret VS EHOME第二局
2016/02/26 DOTA
在Python中用keys()方法返回字典键的教程
2015/05/21 Python
Python json 错误xx is not JSON serializable解决办法
2017/03/15 Python
python实现机械分词之逆向最大匹配算法代码示例
2017/12/13 Python
Django处理多用户类型的方法介绍
2019/05/18 Python
pyqt5 键盘监听按下enter 就登陆的实例
2019/06/25 Python
Python 实现日志同时输出到屏幕和文件
2020/02/19 Python
纯CSS3实现圆圈动态发光特效动画的示例代码
2021/03/08 HTML / CSS
在html5的Canvas上绘制椭圆的几种方法总结
2013/01/07 HTML / CSS
华纳兄弟工作室的官方授权商店:WB Shop
2018/11/30 全球购物
缓刑人员的思想汇报
2014/01/11 职场文书
舞蹈专业大学生职业规划范文
2014/03/12 职场文书
微笑面对生活演讲稿
2014/09/23 职场文书
2014年发展党员工作总结
2014/11/12 职场文书
2015年国庆节新闻稿
2015/07/18 职场文书
团结主题班会
2015/08/13 职场文书
我的中国梦主题班会
2015/08/14 职场文书
上级领导检查欢迎词
2015/09/30 职场文书
MATLAB 全景图切割及盒图显示的实现步骤
2021/05/14 Python
Nginx虚拟主机的搭建的实现步骤
2022/01/18 Servers