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获得图片base64编码示例
Jan 16 Python
Python实现二维有序数组查找的方法
Apr 27 Python
python中list列表的高级函数
May 17 Python
python生成式的send()方法(详解)
May 08 Python
django定期执行任务(实例讲解)
Nov 03 Python
Python3中条件控制、循环与函数的简易教程
Nov 21 Python
TensorFlow 滑动平均的示例代码
Jun 19 Python
pygame实现雷电游戏雏形开发
Nov 20 Python
学生信息管理系统Python面向对象版
Jan 30 Python
解决py2exe打包后,总是多显示一个DOS黑色窗口的问题
Jun 21 Python
15行Python代码实现免费发送手机短信推送消息功能
Feb 27 Python
pyecharts在数据可视化中的应用详解
Jun 08 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
Zend Framework动作助手FlashMessenger用法详解
2016/03/05 PHP
获取页面高度,窗口高度,滚动条高度等参数值getPageSize,getPageScroll
2006/09/22 Javascript
jquery Firefox3.5中操作select的问题
2009/07/10 Javascript
JavaScript Event学习补遗 addEventSimple
2010/02/11 Javascript
五段实用的js高级技巧
2011/12/20 Javascript
node.js chat程序如何实现Ajax long-polling长链接刷新模式
2012/03/13 Javascript
jQuery 1.8 Release版本发布了
2012/08/14 Javascript
jquery中object对象循环遍历的方法
2015/12/18 Javascript
Nodejs express框架一个工程中同时使用ejs模版和jade模版
2015/12/28 NodeJs
BOM之navigator对象和用户代理检测
2017/02/10 Javascript
使用vue.js编写蓝色拼图小游戏
2017/03/17 Javascript
React.js中常用的ES6写法总结(推荐)
2017/05/09 Javascript
重学JS之显示强制类型转换详解
2019/06/30 Javascript
VUE 实现动态给对象增加属性,并触发视图更新操作示例
2019/11/29 Javascript
vue中template的三种写法示例
2020/10/21 Javascript
[48:35]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 TNC vs Optic
2018/04/03 DOTA
总结Python中逻辑运算符的使用
2015/05/13 Python
python实现Windows电脑定时关机
2018/06/20 Python
手把手教你如何安装Pycharm(详细图文教程)
2018/11/28 Python
对python dataframe逻辑取值的方法详解
2019/01/30 Python
详解PyCharm安装MicroPython插件的教程
2019/06/24 Python
如何利用Anaconda配置简单的Python环境
2019/06/24 Python
Flask配置Cors跨域的实现
2019/07/12 Python
python是否适合网页编程详解
2019/10/04 Python
Python 实现自动导入缺失的库
2019/10/29 Python
解决pytorch报错:AssertionError: Invalid device id的问题
2020/01/10 Python
Tensorflow进行多维矩阵的拆分与拼接实例
2020/02/07 Python
python GUI库图形界面开发之PyQt5信号与槽基本操作
2020/02/25 Python
python 两种方法修改文件的创建时间、修改时间、访问时间
2020/09/26 Python
html5+css3气泡组件的实现
2014/11/21 HTML / CSS
VIVOBAREFOOT赤脚鞋:让您的脚做自然的事情
2017/06/01 全球购物
中软国际Java程序员笔试题
2014/07/19 面试题
致短跑运动员广播稿
2014/01/09 职场文书
园艺专业毕业生求职信
2014/09/02 职场文书
老人与海读书笔记
2015/06/26 职场文书
世界文化遗产导游词
2019/08/07 职场文书