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读取注册表中值的方法
Apr 08 Python
python 删除列表里所有空格项的方法总结
Apr 18 Python
对numpy中的数组条件筛选功能详解
Jul 02 Python
详解Python Matplot中文显示完美解决方案
Mar 07 Python
详解python数据结构和算法
Apr 18 Python
Selenium+Python 自动化操控登录界面实例(有简单验证码图片校验)
Jun 28 Python
pandas的连接函数concat()函数的具体使用方法
Jul 09 Python
Python pandas自定义函数的使用方法示例
Nov 20 Python
python使用for...else跳出双层嵌套循环的方法实例
May 17 Python
解决pycharm导入本地py文件时,模块下方出现红色波浪线的问题
Jun 01 Python
python脚本和网页有何区别
Jul 02 Python
Python中的协程(Coroutine)操作模块(greenlet、gevent)
May 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
php扩展ZF――Validate扩展
2008/01/10 PHP
解析php中static,const与define的使用区别
2013/06/18 PHP
有关PHP性能优化的介绍
2013/06/20 PHP
PHP连接Access数据库的方法小结
2013/06/20 PHP
php判断输入是否是纯数字,英文,汉字的方法
2015/03/05 PHP
session 加入redis的实现代码
2016/07/15 PHP
SyntaxHighlighter代码加色使用方法
2008/09/07 Javascript
jquery键盘事件介绍
2011/01/31 Javascript
javascript相等运算符与等同运算符详细介绍
2013/11/09 Javascript
javascript中的取反再取反~~没有意义
2014/04/06 Javascript
js图片上传前预览功能(兼容所有浏览器)
2016/08/24 Javascript
html中鼠标滚轮事件onmousewheel的处理方法
2016/11/11 Javascript
jQuery事件绑定方法学习总结(推荐)
2016/11/21 Javascript
原生Javascript插件开发实践
2017/01/18 Javascript
JavaScript如何使用插值实现图像渐变
2020/06/28 Javascript
Vue $emit()不能触发父组件方法的原因及解决
2020/07/28 Javascript
使用Webpack 搭建 Vue3 开发环境过程详解
2020/07/28 Javascript
Python对小数进行除法运算的正确方法示例
2014/08/25 Python
用tensorflow实现弹性网络回归算法
2018/01/09 Python
解决Python 爬虫URL中存在中文或特殊符号无法请求的问题
2018/05/11 Python
Python subprocess模块功能与常见用法实例详解
2018/06/28 Python
python数据归一化及三种方法详解
2019/08/06 Python
Python+OpenCV实现实时眼动追踪的示例代码
2019/11/11 Python
利用pyshp包给shapefile文件添加字段的实例
2019/12/06 Python
QML用PathView实现轮播图
2020/06/03 Python
iframe与window.onload如何使用详解
2020/05/07 HTML / CSS
奥地利领先的在线药房:SHOP APOTHEKE
2019/10/07 全球购物
Vuori官网:运动服装的终级表现
2021/01/27 全球购物
家长给幼儿园的表扬信
2014/01/09 职场文书
黄河的主人教学反思
2014/02/07 职场文书
班级旅游计划书
2014/05/03 职场文书
陈胜吴广起义口号
2014/06/20 职场文书
大学生工作求职信
2014/06/23 职场文书
2014教师“四风问题”对照检查材料思想汇报
2014/09/16 职场文书
诚实守信主题班会
2015/08/13 职场文书
Mysql效率优化定位较低sql的两种方式
2021/05/26 MySQL