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 相关文章推荐
Flask框架中密码的加盐哈希加密和验证功能的用法详解
Jun 07 Python
Python基础教程之浅拷贝和深拷贝实例详解
Jul 15 Python
python实现守护进程、守护线程、守护非守护并行
May 05 Python
Python实现判断一行代码是否为注释的方法
May 23 Python
Python实现的远程登录windows系统功能示例
Jun 21 Python
Python2和Python3.6环境解决共存问题
Nov 09 Python
Python反爬虫技术之防止IP地址被封杀的讲解
Jan 09 Python
Opencv+Python实现图像运动模糊和高斯模糊的示例
Apr 11 Python
Python如何使用队列方式实现多线程爬虫
May 12 Python
解决django框架model中外键不落实到数据库问题
May 20 Python
python如何停止递归
Sep 09 Python
python基于opencv 实现图像时钟
Jan 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读取msn上的用户信息类
2008/12/05 PHP
php5.4以下版本json不支持不转义内容中文的解决方法
2015/01/13 PHP
ThinkPHP整合datatables实现服务端分页的示例代码
2018/02/10 PHP
解决在laravel中leftjoin带条件查询没有返回右表为NULL的问题
2019/10/15 PHP
javascript显示隐藏层比较不错的方法分析
2008/09/30 Javascript
CSS鼠标响应事件经过、移动、点击示例介绍
2013/09/04 Javascript
JavaScript使用DeviceOne开发实战(四)仿优酷视频应用
2015/12/02 Javascript
JS在一定时间内跳转页面及各种刷新页面的实现方法
2016/05/26 Javascript
js中常用的Tab切换效果(推荐)
2016/08/30 Javascript
JS模拟实现ECMAScript5新增的数组方法
2017/03/20 Javascript
Angular 2.0+ 的数据绑定的实现示例
2017/08/09 Javascript
VSCode 配置React Native开发环境的方法
2017/12/27 Javascript
vue使用技巧及vue项目中遇到的问题
2018/06/04 Javascript
利用node.js开发cli的完整步骤
2020/12/29 Javascript
使用python实现拉钩网上的FizzBuzzWhizz问题示例
2014/05/05 Python
python中常用检测字符串相关函数汇总
2015/04/15 Python
详解Python函数可变参数定义及其参数传递方式
2017/08/02 Python
python面向对象多线程爬虫爬取搜狐页面的实例代码
2018/05/31 Python
python三大神器之fabric使用教程
2019/06/10 Python
详解用python计算阶乘的几种方法
2019/08/14 Python
python利用datetime模块计算程序运行时间问题
2020/02/20 Python
HTML5 canvas基本绘图之图形组合
2016/06/27 HTML / CSS
GNC健安喜美国官网:美国第一营养品牌
2016/07/22 全球购物
Sofmap官网:日本著名的数码电器专卖店
2017/05/19 全球购物
科茨沃尔德家居商店:Scotts of Stow
2018/06/29 全球购物
Diamondback自行车:拥有你的冒险
2019/04/22 全球购物
幼师自荐信
2013/10/26 职场文书
大学生创业感言
2014/01/25 职场文书
毕业典礼演讲稿
2014/05/13 职场文书
计算机多媒体专业自荐信
2014/07/04 职场文书
党的群众路线教育实践活动个人整改方案
2014/09/21 职场文书
七年级上册语文教学计划
2015/01/22 职场文书
写给媳妇的检讨书
2015/05/06 职场文书
2015年学校心理健康教育工作总结
2015/05/11 职场文书
写作技巧:如何撰写一份优秀的营销策划书
2019/08/13 职场文书
SQL中的连接查询详解
2022/06/21 SQL Server