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使用reportlab画图示例(含中文汉字)
Dec 03 Python
简单了解Django模板的使用
Dec 20 Python
Python简单定义与使用二叉树示例
May 11 Python
python实现简单加密解密机制
Mar 19 Python
Opencv+Python实现图像运动模糊和高斯模糊的示例
Apr 11 Python
Django框架实现分页显示内容的方法详解
May 10 Python
Python面向对象之Web静态服务器
Sep 03 Python
Python3的unicode编码转换成中文的问题及解决方案
Dec 10 Python
如何在python中实现线性回归
Aug 10 Python
JupyterNotebook 输出窗口的显示效果调整实现
Sep 22 Python
解决hive中导入text文件遇到的坑
Apr 07 Python
python turtle绘图
May 04 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服务器实现多session并发运行
2006/10/09 PHP
PHP全局变量与超级全局变量区别分析
2016/04/01 PHP
解决form中action属性后面?传递参数 获取不到的问题
2017/07/21 PHP
laravel异步监控定时调度器实例详解
2019/06/21 PHP
javascript:void(0)是什么意思示例介绍
2013/11/17 Javascript
Internet Explorer 11 浏览器介绍:别叫我IE
2014/09/28 Javascript
用简洁的jQuery方法toggleClass实现隔行换色
2014/10/22 Javascript
JQuery控制div外点击隐藏而div内点击不会隐藏的方法
2015/01/13 Javascript
jquery手风琴特效插件
2015/02/04 Javascript
JS实现让网页背景图片斜向移动的方法
2015/02/25 Javascript
jQuery UI插件自定义confirm确认框的方法
2015/03/20 Javascript
JavaScript实现事件的中断传播和行为阻止方法示例
2017/01/20 Javascript
jQuery遮罩层实例讲解
2017/05/11 jQuery
vue.js 左侧二级菜单显示与隐藏切换的实例代码
2017/05/23 Javascript
JQuery Ajax 异步操作之动态添加节点功能
2017/05/24 jQuery
D3.js进阶系列之CSV表格文件的读取详解
2017/06/06 Javascript
前端vue+elementUI如何实现记住密码功能
2020/09/20 Javascript
[50:50]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第一场 12.20
2020/12/23 DOTA
深入Python解释器理解Python中的字节码
2015/04/01 Python
python中随机函数random用法实例
2015/04/30 Python
Python中list列表的一些进阶使用方法介绍
2015/08/15 Python
编写Python爬虫抓取豆瓣电影TOP100及用户头像的方法
2016/01/20 Python
详解python使用Nginx和uWSGI来运行Python应用
2018/01/09 Python
Python实用技巧之利用元组代替字典并为元组元素命名
2018/07/11 Python
Python解析命令行读取参数之argparse模块
2019/07/26 Python
python语音识别指南终极版(有这一篇足矣)
2020/09/09 Python
一款纯css3实现的颜色渐变按钮的代码教程
2014/11/12 HTML / CSS
WatchShop法国:英国排名第一的独立手表零售商
2020/02/17 全球购物
浅谈react路由传参的几种方式
2021/03/23 Javascript
2014新课程改革心得体会
2014/03/10 职场文书
需求分析说明书
2014/05/09 职场文书
教育专业毕业生推荐信
2014/07/10 职场文书
布达拉宫的导游词
2015/02/02 职场文书
英文产品推荐信
2015/03/27 职场文书
美德少年主要事迹材料
2015/11/04 职场文书
传单、海报早OUT了,另类传单营销方案送给你!
2019/07/15 职场文书