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数据结构之图深度优先和广度优先实例详解
Jul 08 Python
Python常用库推荐
Dec 04 Python
详解python之简单主机批量管理工具
Jan 27 Python
Python实现感知机(PLA)算法
Dec 20 Python
python 通过SSHTunnelForwarder隧道连接redis的方法
Feb 19 Python
python的debug实用工具 pdb详解
Jul 12 Python
python 消费 kafka 数据教程
Dec 21 Python
python如何建立全零数组
Jul 19 Python
Elasticsearch py客户端库安装及使用方法解析
Sep 14 Python
python爬虫利用selenium实现自动翻页爬取某鱼数据的思路详解
Dec 22 Python
详解python第三方库的安装、PyInstaller库、random库
Mar 03 Python
如何使用Tkinter进行窗口的管理与设置
Jun 30 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引擎的发展
2006/11/16 PHP
PHP生成二维码的两个方法和实例
2014/07/01 PHP
你应该知道PHP浮点数知识
2015/05/13 PHP
jQuery each()小议
2010/03/18 Javascript
javascript与CSS复习(二)
2010/06/29 Javascript
jQuery实现点击后标记当前菜单位置(背景高亮菜单)效果
2015/08/22 Javascript
基于javascript实现全屏漂浮广告
2016/03/31 Javascript
微信小程序 scroll-view实现上拉加载与下拉刷新的实例
2017/01/21 Javascript
js实现截图保存图片功能的代码示例
2017/02/16 Javascript
利用Chrome DevTools直接调试Node.js和JavaScript的方法详解(并行)
2017/02/16 Javascript
详解angular 中的自定义指令之详解API
2017/06/20 Javascript
基于Jquery Ajax type的4种类型(详解)
2017/08/02 jQuery
Angularjs自定义指令实现分页插件(DEMO)
2017/09/16 Javascript
vue + element-ui实现简洁的导入导出功能
2017/12/22 Javascript
[07:26]2015国际邀请赛第二日TOP10集锦
2015/08/06 DOTA
Python中for循环详解
2014/01/17 Python
python实现给数组按片赋值的方法
2015/07/28 Python
Python pass详细介绍及实例代码
2016/11/24 Python
Python实现动态添加属性和方法操作示例
2018/07/25 Python
详解Python数据可视化编程 - 词云生成并保存(jieba+WordCloud)
2019/03/26 Python
浅谈keras使用预训练模型vgg16分类,损失和准确度不变
2020/07/02 Python
django前端页面下拉选择框默认值设置方式
2020/08/09 Python
详解Python 函数参数的拆解
2020/09/02 Python
CSS3属性box-shadow使用指南
2014/12/09 HTML / CSS
凯蒂·佩里个人女鞋品牌:Katy Perry Collections
2019/04/04 全球购物
雷曼兄弟的五金店:Lehman’s Hardware Store
2019/04/10 全球购物
什么是索引指示器
2012/08/20 面试题
地理科学专业毕业生求职信
2013/10/15 职场文书
科长个人四风问题整改措施思想汇报
2014/10/13 职场文书
社区党风廉政建设调研报告
2015/01/01 职场文书
2015年纪检监察工作总结
2015/04/08 职场文书
土建施工员岗位职责
2015/04/11 职场文书
食堂管理制度范本
2015/08/04 职场文书
2019商业计划书格式、范文
2019/04/24 职场文书
Nginx解决403 forbidden的完整步骤
2021/04/01 Servers
如何Python使用re模块实现okenizer
2022/04/30 Python