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 15 Python
使用Python压缩和解压缩zip文件的教程
May 06 Python
Python实现多线程抓取妹子图
Aug 08 Python
python爬取微信公众号文章
Aug 31 Python
详解python实现数据归一化处理的方式:(0,1)标准化
Jul 17 Python
python对常见数据类型的遍历解析
Aug 27 Python
Django实现auth模块下的登录注册与注销功能
Oct 10 Python
使用python代码进行身份证号校验的实现示例
Nov 21 Python
Python 词典(Dict) 加载与保存示例
Dec 06 Python
python实现人脸签到系统
Apr 13 Python
Selenium之模拟登录铁路12306的示例代码
Jul 31 Python
python 调用Google翻译接口的方法
Dec 09 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
便携利器 — TECSUN PL-365简评
2021/03/02 无线电
php strftime函数的详细用法
2018/06/21 PHP
JavaScript实现自己的DOM选择器原理及代码
2013/03/04 Javascript
JavaScript学习笔记之基础语法
2015/01/22 Javascript
javascript中call,apply,bind的用法对比分析
2015/02/12 Javascript
js代码实现点击按钮出现60秒倒计时
2021/01/28 Javascript
轻松实现jquery手风琴效果
2016/01/14 Javascript
如何消除inline-block属性带来的标签间间隙
2016/03/31 Javascript
javascript冒泡排序小结
2016/04/10 Javascript
AngularJS ng-change 指令的详解及简单实例
2016/07/30 Javascript
bootstrap模态框实现拖拽效果
2016/12/14 Javascript
浅析BootStrap中Modal(模态框)使用心得
2016/12/24 Javascript
浅谈AngularJS中使用$resource(已更新)
2017/09/14 Javascript
原生JS写Ajax的请求函数功能
2017/12/22 Javascript
详解Vue.js在页面加载时执行某个方法
2018/11/20 Javascript
JavaScript格式化json和xml的方法示例
2019/01/22 Javascript
前端插件之Bootstrap Dual Listbox使用教程
2019/07/23 Javascript
package.json各个属性说明详解
2020/03/11 Javascript
Vue的Options用法说明
2020/08/14 Javascript
浅析python打包工具distutils、setuptools
2018/04/20 Python
Tornado Web Server框架编写简易Python服务器
2018/07/28 Python
详解Django项目中模板标签及模板的继承与引用(网站中快速布置广告)
2019/03/27 Python
基于Pycharm加载多个项目过程图解
2020/01/19 Python
基于Tensorflow高阶读写教程
2020/02/10 Python
Python 的 __str__ 和 __repr__ 方法对比
2020/09/02 Python
python3 kubernetes api的使用示例
2021/01/12 Python
css3实现背景动态渐变效果
2019/12/10 HTML / CSS
英国领先的维生素和营养补充剂直接供应商:Healthspan
2019/04/22 全球购物
SQL Server 2000数据库的文件有哪些,分别进行描述。
2015/11/09 面试题
应届护士推荐信
2013/11/16 职场文书
写演讲稿所需要注意的4个条件
2014/01/09 职场文书
小摄影师教学反思
2014/04/27 职场文书
运动会报道稿300字
2014/10/02 职场文书
六一儿童节开幕词
2015/01/29 职场文书
Python djanjo之csrf防跨站攻击实验过程
2021/05/14 Python
SQLServer中exists和except用法介绍
2021/12/04 SQL Server