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的内存
Dec 17 Python
Python编程判断一个正整数是否为素数的方法
Apr 14 Python
删除python pandas.DataFrame 的多重index实例
Jun 08 Python
详解Python的数据库操作(pymysql)
Apr 04 Python
Python字符串内置函数功能与用法总结
Apr 16 Python
python Opencv计算图像相似度过程解析
Dec 03 Python
python函数调用,循环,列表复制实例
May 03 Python
利用python中的matplotlib打印混淆矩阵实例
Jun 16 Python
解决PyCharm不在run输出运行结果而不是再Console里输出的问题
Sep 21 Python
python实现计算图形面积
Feb 22 Python
Python的flask接收前台的ajax的post数据和get数据的方法
Apr 12 Python
python 判断文件或文件夹是否存在
Mar 18 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正则
2006/07/07 PHP
php 数组二分法查找函数代码
2010/02/16 PHP
php 截取字符串并以零补齐str_pad() 函数
2011/05/07 PHP
php使用imagick模块实现图片缩放、裁剪、压缩示例
2014/04/17 PHP
PHP实现AES256加密算法实例
2014/09/22 PHP
php从文件夹随机读取文件的方法
2015/06/01 PHP
WordPress中用于获取文章信息以及分类链接的函数用法
2015/12/18 PHP
PHP 无限级分类
2017/05/04 PHP
基于php数组中的索引数组和关联数组详解
2018/03/12 PHP
Javascript 写的简单进度条控件
2008/01/22 Javascript
第一个JavaScript入门基础 document.write输出
2010/02/22 Javascript
基于jquery的兼容各种浏览器的iframe自适应高度的脚本
2010/08/13 Javascript
JS中不为人知的五种声明Number的方式简要概述
2013/02/22 Javascript
jQuery获取Radio,CheckBox选择的Value值(示例代码)
2013/12/12 Javascript
javascript日期对象格式化为字符串的实现方法
2014/01/14 Javascript
jquery.ajax的url中传递中文乱码问题的解决方法
2014/02/07 Javascript
javascript等号运算符使用详解
2015/04/16 Javascript
javascript实现图片延迟加载方法汇总(三种方法)
2015/08/27 Javascript
Angularjs全局变量被作用域监听的正确姿势
2016/02/06 Javascript
使用jQuery实现一个类似GridView的编辑,更新,取消和删除的功能
2017/03/15 Javascript
php 修改密码实现代码
2017/05/24 Javascript
详解HTTPS 的原理和 NodeJS 的实现
2017/07/04 NodeJs
Vue Transition实现类原生组件跳转过渡动画的示例
2017/08/19 Javascript
vue data变量相互赋值后被实时同步的解决步骤
2020/08/05 Javascript
python3+PyQt5实现使用剪贴板做复制与粘帖示例
2017/01/24 Python
Python中的is和==比较两个对象的两种方法
2017/09/06 Python
Django 实现图片上传和显示过程详解
2019/07/18 Python
解决tensorflow添加ptb库的问题
2020/02/10 Python
详解HTML5 录音的踩坑之旅
2017/12/26 HTML / CSS
荷兰时尚精品店:Labels Fashion
2020/03/22 全球购物
事业单位绩效考核实施方案
2014/03/27 职场文书
知识就是力量演讲稿
2014/09/13 职场文书
云台山导游词
2015/02/03 职场文书
闪闪红星观后感
2015/06/08 职场文书
导游词之江苏溱潼古镇
2019/11/27 职场文书
SpringBoot 集成Redis 过程
2021/06/02 Redis