python3 字典dict的综合运用(这是一段意外写出来的程序代码)

介绍

计划和媳妇去云南旅游,媳妇让做一下预算,正好当时正在写python代码,就随手一个print(sum([...]))计算了出来,后来媳妇说分分类,有些是确定的,有些无法确定,就又加了些逻辑进去,媳妇称赞的同时又灵魂一击:一个计算器不就解决了吗?哈哈哈,最后本着“杀鸡用牛刀”的目的,又花了些时间完善了一下代码逻辑和注释。
该小段代码主要用了字典dict、求和sum()以及逻辑判断,既然写了就发出来,说不定可以帮助到某位同学呢(大牛大神们请绕开,不敢班门弄斧U_U),另外需要说明的是,该代码中的字典只是为了应用,所以不包含字典的所有用法。

源码

# 根据费项计算总费用
def sumFees(fees):
    '''
    参数说明:
        1、fees为一个两层级的字典,外层字典的value必须为字典格式,否则会被忽略
        2、内层的字典的value必须为数字,否则可能会强制转为0
        3、内层的字典的value如果为负数,也会正常进行运算
    
    示例格式:
        fees = {
            '机票': {'北京 >>> 昆明': 803*2, '丽江 >>> 郑州': 900*2},
            '住宿': {'大理古城': 300, '大理市区': 200, '丽江': 588, 'y郑州': 150*4},
            '租车': {'大理': 135},
            '铁路': {'昆明 >>> 大理': 145*2, '大理 >>> 丽江': 49*2, '郑州 >>> 北京': 309*2},
            '门票': {'苍山景区': 290*2, '环洱海景点': 200*2, 'y丽江千古情': 230*2, 'y玉龙雪山': 438},
            '餐食': {'大理': 1000, 'y丽江': 1087, 'y郑州':879},
            '购物': {'大理': 2000, 'y丽江': 1500},
            '其他': {'y公共交通': 40*2+20*2+6*2+20*2, '租车油费':76, '保险':20*2+12*2}
        }
    '''
    # 如果传参不是字典类型,直接处理
    if not isinstance(fees, dict):
        print('传参不是字典类型,请重新设置!')
        return ''

    # 定义空字典,供后面使用
    noConfirm = {}  # 预估费用明细
    confirmed = {}  # 确定费用明细
    totalFees = {}  # 总费用明细
    totalFeesConfirmed = {}  # 确定总费用明细
    totalFeesNoConfirm = {}  # 预估总费用明细

    # 第一个for循环:处理外层字典
    for item in fees:
        itemValueTem = fees[item]
        temDict1 = {}
        temDict2 = {}

        #判断外层字典的value是否为字典
        if isinstance(itemValueTem, dict):
            # 第二个for循环:处理内层字典
            for item2 in itemValueTem:
                itemValue = itemValueTem[item2]
                # 判断内层字典的value是否为数值,如果不是数值,则强制转换为浮点数,转换失败则强制赋值为0
                if not isinstance(itemValue, (int, float)):
                    try:
                        itemValue = float(itemValue)
                    except:
                        itemValue = 0

                # 如果内层字典的key的第一个字符为“y”,则记为预估费用项,否则记为确定费用项
                if item2[0:1].lower() == 'y':
                    temDict1[item2] = itemValue
                else:
                    temDict2[item2] = itemValue

            # 只有临时预估费用和临时确定费用不为空的时候才进入到noConfirm和confirmed
            if temDict1:
                noConfirm[item] = temDict1
            if temDict2:
                confirmed[item] = temDict2
        else:
            print('%s 的参数设置错误,必须为dict类型!' % (item,))

    # 确定费用项不为空时,处理确定费用项
    if confirmed:
        for item3 in confirmed:
            # 获取各确定费用项的value,返回一个列表
            feeTem3 = confirmed[item3].values()

            # 如果列表feeTem3不为空则计算确定总费用,并进入到totalFees和totalFeesConfirmed中
            if feeTem3:
                item3Sum = sum(feeTem3)
                totalFees[item3] = item3Sum
                totalFeesConfirmed[item3] = item3Sum
                # print('%s 的确定总费用为 %s 元' %(item3, str(item3Sum)))

    # 预估费用项不为空时,处理预估费用项
    if noConfirm:
        for item4 in noConfirm:
            # 获取各预估费用项的value,返回一个列表
            feeTem4 = noConfirm[item4].values()

            # 如果列表feeTem4不为空则计算预估总费用,并进入到totalFees和totalFeesNoConfirm中
            if feeTem4:
                item4Sum = sum(feeTem4)
                # print('%s 的预估总费用为 %s 元' %(item4, str(item4Sum)))
                totalFeesNoConfirm[item4] = item4Sum
                if item4 not in totalFees:
                    totalFees[item4] = item4Sum

                # 如果预估费用项在总费用中已存在(内层字典中有确定费用也有预估费用),则和已存在的数据相加求和后再赋值
                else:
                    totalFees[item4] = item4Sum + totalFees[item4]

    # 如果总费用明细totalFees不为空,进行计算并打印
    if totalFees:
        totalFee = sum(totalFees.values())
        totalFeeConfirmed = sum(totalFeesConfirmed.values())
        totalFeeNoConfirm = sum(totalFeesNoConfirm.values())

        # 全部都是确定费用项的处理方式
        if not noConfirm:
            print('总费用(确定):', totalFee)
            print('总费用明细(确定):', totalFees)
            print('费用明细(确定):', confirmed)
            print('没有预估费用')

        # 全部都是预估费用项的处理方式
        elif not confirmed:
            print('总费用(预估):', totalFee)
            print('总费用明细(预估):', totalFees)
            print('费用明细(预估):', noConfirm)
            print('没有确定费用')

        # 同时有确定费用项和预估费用项的处理方式
        else:
            print('总费用:%s(确定:%s,预估:%s)' % (str(totalFee), str(totalFeeConfirmed), str(totalFeeNoConfirm)))
            print('总费用明细(确定):', totalFeesConfirmed)
            print('总费用明细(预估):', totalFeesNoConfirm)
            print('费用明细(确定):', confirmed)
            print('费用明细(预估):', noConfirm)
    else:
        print('没有设置数据!')

    # 为了保证函数的完整性,添加一个空返回值
    return ''

函数调用及执行结果(以下都是测试数据,不是我俩旅行的实际费用)

调用1:确定费用项和预估费用项都有

if __name__ == '__main__':
    travelFees = {
        '机票': {'北京 >>> 昆明': 803*2, '丽江 >>> 郑州': 900*2},
        '住宿': {'大理古城': 300, '大理市区': 200, '丽江': 588, 'y郑州': 150*4},
        '租车': {'大理': 135},
        '铁路': {'昆明 >>> 大理': 145*2, '大理 >>> 丽江': 49*2, '郑州 >>> 北京': 309*2},
        '门票': {'苍山景区': 290*2, '环洱海景点': 200*2, 'y丽江千古情': 230*2, 'y玉龙雪山': 438},
        '餐食': {'大理': 1000, 'y丽江': 1087, 'y郑州':879},
        '购物': {'大理': 2000, 'y丽江': 1500},
        '其他': {'y公共交通': 40*2+20*2+6*2+20*2, '租车油费':76, '保险':20*2+12*2}
    }
    sumFees(travelFees)

执行结果
总费用:14891(确定:9755,预估:5136)
总费用明细(确定): {'机票': 3406, '住宿': 1088, '租车': 135, '铁路': 1006, '门票': 980, '餐食': 1000, '购物': 2000, '其他': 140}
总费用明细(预估): {'住宿': 600, '门票': 898, '餐食': 1966, '购物': 1500, '其他': 172}
费用明细(确定): {'机票': {'北京 >>> 昆明': 1606, '丽江 >>> 郑州': 1800}, '住宿': {'大理古城': 300, '大理市区': 200, '丽江': 588}, '租车': {'大理': 135}, '铁路': {'昆明 >>> 大理': 290, '大理 >>> 丽江': 98, '郑州 >>> 北京': 618}, '门票': {'苍山景区': 580, '环洱海景点': 400}, '餐食': {'大理': 1000}, '购物': {'大理': 2000}, '其他': {'租车油费': 76, '保险': 64}}
费用明细(预估): {'住宿': {'y郑州': 600}, '门票': {'y丽江千古情': 460, 'y玉龙雪山': 438}, '餐食': {'y丽江': 1087, 'y郑州': 879}, '购物': {'y丽江': 1500}, '其他': {'y公共交通': 172}}

调用2:只有确定费用项

if __name__ == '__main__':
    travelFees = {
        '机票': {'北京 >>> 昆明': 803*2, '丽江 >>> 郑州': 900*2},
        # '住宿': {'大理古城': 300, '大理市区': 200, '丽江': 588, 'y郑州': 150*4},
        '租车': {'大理': 135},
        '铁路': {'昆明 >>> 大理': 145*2, '大理 >>> 丽江': 49*2, '郑州 >>> 北京': 309*2},
        # '门票': {'苍山景区': 290*2, '环洱海景点': 200*2, 'y丽江千古情': 230*2, 'y玉龙雪山': 438},
        # '餐食': {'大理': 1000, 'y丽江': 1087, 'y郑州':879},
        # '购物': {'大理': 2000, 'y丽江': 1500},
        # '其他': {'y公共交通': 40*2+20*2+6*2+20*2, '租车油费':76, '保险':20*2+12*2}
    }
    sumFees(travelFees)

执行结果
总费用(确定): 4547
总费用明细(确定): {'机票': 3406, '租车': 135, '铁路': 1006}
费用明细(确定): {'机票': {'北京 >>> 昆明': 1606, '丽江 >>> 郑州': 1800}, '租车': {'大理': 135}, '铁路': {'昆明 >>> 大理': 290, '大理 >>> 丽江': 98, '郑州 >>> 北京': 618}}
没有预估费用

调用3:只有预估费用项

if __name__ == '__main__':
    travelFees = {
        # '机票': {'北京 >>> 昆明': 803*2, '丽江 >>> 郑州': 900*2},
        # '住宿': {'大理古城': 300, '大理市区': 200, '丽江': 588, 'y郑州': 150*4},
        '租车': {'y大理': 135},
        # '铁路': {'昆明 >>> 大理': 145*2, '大理 >>> 丽江': 49*2, '郑州 >>> 北京': 309*2},
        '门票': {'y苍山景区': 290*2, 'y环洱海景点': 200*2, 'y丽江千古情': 230*2, 'y玉龙雪山': 438},
        '餐食': {'y大理': 1000, 'y丽江': 1087, 'y郑州':879},
        # '购物': {'大理': 2000, 'y丽江': 1500},
        '其他': {'y公共交通': 40*2+20*2+6*2+20*2, 'y租车油费':76, 'y保险':20*2+12*2}
    }
    sumFees(travelFees)

执行结果
总费用(预估): 5291
总费用明细(预估): {'租车': 135, '门票': 1878, '餐食': 2966, '其他': 312}
费用明细(预估): {'租车': {'y大理': 135}, '门票': {'y苍山景区': 580, 'y环洱海景点': 400, 'y丽江千古情': 460, 'y玉龙雪山': 438}, '餐食': {'y大理': 1000, 'y丽江': 1087, 'y郑州': 879}, '其他': {'y公共交通': 172, 'y租车油费': 76, 'y保险': 64}}
没有确定费用

调用4:内层字典的value有非数字类型

if __name__ == '__main__':
    travelFees = {
        '机票': {'北京 >>> 昆明': 803*2, '丽江 >>> 郑州': 900*2},
        '住宿': {'大理古城': 300, '大理市区': 'hello', '丽江': '588', 'y郑州': 150*4},
        '租车': {'y大理': 'test135'},
        # '铁路': {'昆明 >>> 大理': 145*2, '大理 >>> 丽江': 49*2, '郑州 >>> 北京': 309*2},
        # '门票': {'y苍山景区': 290*2, 'y环洱海景点': 200*2, 'y丽江千古情': 230*2, 'y玉龙雪山': 438},
        # '餐食': {'y大理': 1000, 'y丽江': 1087, 'y郑州':879},
        '购物': {'大理': 2000, 'y丽江': '1500'},
        # '其他': {'y公共交通': 40*2+20*2+6*2+20*2, 'y租车油费':76, 'y保险':20*2+12*2}
    }
    sumFees(travelFees)

执行结果
总费用:8394.0(确定:6294.0,预估:2100.0)
总费用明细(确定): {'机票': 3406, '住宿': 888.0, '购物': 2000}
总费用明细(预估): {'住宿': 600, '租车': 0, '购物': 1500.0}
费用明细(确定): {'机票': {'北京 >>> 昆明': 1606, '丽江 >>> 郑州': 1800}, '住宿': {'大理古城': 300, '大理市区': 0, '丽江': 588.0}, '购物': {'大理': 2000}}
费用明细(预估): {'住宿': {'y郑州': 600}, '租车': {'y大理': 0}, '购物': {'y丽江': 1500.0}}

调用5:内层字典没有数据

if __name__ == '__main__':
    travelFees = {
        # '机票': {'北京 >>> 昆明': 803*2, '丽江 >>> 郑州': 900*2},
        # '住宿': {'大理古城': 300, '大理市区': 200, '丽江': 588, 'y郑州': 150*4},
        # '租车': {'y大理': 135},
        # '铁路': {'昆明 >>> 大理': 145*2, '大理 >>> 丽江': 49*2, '郑州 >>> 北京': 309*2},
        # '门票': {'y苍山景区': 290*2, 'y环洱海景点': 200*2, 'y丽江千古情': 230*2, 'y玉龙雪山': 438},
        # '餐食': {'y大理': 1000, 'y丽江': 1087, 'y郑州':879},
        # '购物': {'大理': 2000, 'y丽江': 1500},
        # '其他': {'y公共交通': 40*2+20*2+6*2+20*2, 'y租车油费':76, 'y保险':20*2+12*2}
    }
    sumFees(travelFees)

执行结果
没有设置数据!

调用6:内层字典有数据,但是数据为空和非字典数据

if __name__ == '__main__':
    travelFees = {
        # '机票': {'北京 >>> 昆明': 803*2, '丽江 >>> 郑州': 900*2},
        '住宿': {},
        '租车': "{'y大理': 135}",
        # '铁路': {'昆明 >>> 大理': 145*2, '大理 >>> 丽江': 49*2, '郑州 >>> 北京': 309*2},
        # '门票': {'y苍山景区': 290*2, 'y环洱海景点': 200*2, 'y丽江千古情': 230*2, 'y玉龙雪山': 438},
        # '餐食': {'y大理': 1000, 'y丽江': 1087, 'y郑州':879},
        # '购物': {'大理': 2000, 'y丽江': 1500},
        # '其他': {'y公共交通': 40*2+20*2+6*2+20*2, 'y租车油费':76, 'y保险':20*2+12*2}
    }
    sumFees(travelFees)

执行结果
租车 的参数设置错误,必须为dict类型!
没有设置数据!

调用7:传参不是字典

if __name__ == '__main__':
    travelFees = 'testd'
    sumFees(travelFees)

执行结果
传参不是字典类型,请重新设置!
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355