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实现自动更换ip的方法
May 05 Python
CentOS中使用virtualenv搭建python3环境
Jun 08 Python
实例讲解Python中SocketServer模块处理网络请求的用法
Jun 28 Python
Python微信企业号开发之回调模式接收微信端客户端发送消息及被动返回消息示例
Aug 21 Python
python编程使用selenium模拟登陆淘宝实例代码
Jan 25 Python
利用django+wechat-python-sdk 创建微信服务器接入的方法
Feb 20 Python
python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan)
Jun 27 Python
python 自动轨迹绘制的实例代码
Jul 05 Python
Python学习笔记之函数的定义和作用域实例详解
Aug 13 Python
vue学习笔记之动态组件和v-once指令简单示例
Feb 29 Python
Python中Selenium对Cookie的操作方法
Jul 09 Python
python实现学生信息管理系统(面向对象)
Jun 05 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
首页四格,首页五格For6.0(GBK)(UTF-8)[12种组合][9-18][版主安装测试通过]
2007/09/24 PHP
php数组函数序列之array_slice() - 在数组中根据条件取出一段值,并返回
2011/11/07 PHP
php while循环得到循环次数
2013/10/26 PHP
php获取服务器端mac和客户端mac的地址支持WIN/LINUX
2014/05/15 PHP
跟我学Laravel之请求与输入
2014/10/15 PHP
php页面函数设置超时限制的方法
2014/12/01 PHP
Ubuntu server 11.04安装memcache及php使用memcache来存储session的方法
2016/05/31 PHP
PHP定时任务获取微信access_token的方法
2016/10/10 PHP
PHP解决高并发的优化方案实例
2020/12/10 PHP
图片onload事件触发问题解决方法
2011/07/31 Javascript
JavaScript面向对象知识串结(读JavaScript高级程序设计(第三版))
2012/07/17 Javascript
jquery 合并内容相同的单元格(示例代码)
2013/12/13 Javascript
jquery数组之存放checkbox全选值示例代码
2013/12/20 Javascript
Egret引擎开发指南之编译项目
2014/09/03 Javascript
js实现浮动在网页右侧的简洁QQ在线客服代码
2015/09/04 Javascript
全面解析Bootstrap表单使用方法(表单控件状态)
2015/11/24 Javascript
深入浅出讲解ES6的解构
2016/08/03 Javascript
node安装--linux下的快速安装教程
2017/03/21 Javascript
详谈for循环里面的break和continue语句
2017/07/20 Javascript
写给vue新手们的vue渲染页面教程
2017/09/01 Javascript
layui实现三级联动效果
2019/07/26 Javascript
vue quill editor 使用富文本添加上传音频功能
2020/01/14 Javascript
vue+elementUI动态增加表单项并添加验证的代码详解
2020/12/17 Vue.js
python http接口自动化脚本详解
2018/01/02 Python
3分钟学会一个Python小技巧
2018/11/23 Python
pyqt实现.ui文件批量转换为对应.py文件脚本
2019/06/19 Python
python实现在函数图像上添加文字和标注的方法
2019/07/08 Python
moosejaw旗下的户外商品促销网站:Mountain Steals
2017/02/27 全球购物
莫斯科大型旅游休闲商品超市:Camping.ru
2020/09/16 全球购物
ShellScript面试题一则-ShellScript编程
2014/06/24 面试题
大二法英学生职业生涯规划范文
2014/02/27 职场文书
西部计划志愿者工作总结
2015/08/11 职场文书
年中了,该如何写好个人述职报告?
2019/07/02 职场文书
mysql配置SSL证书登录的实现
2021/09/04 MySQL
python中的3种定义类方法
2021/11/27 Python
解决Python保存文件名太长OSError: [Errno 36] File name too long
2022/05/11 Python