美文网首页
python3 字典dict的综合运用(这是一段意外写出来的程序

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

作者: AmanWang | 来源:发表于2020-11-04 09:02 被阅读0次

介绍

计划和媳妇去云南旅游,媳妇让做一下预算,正好当时正在写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)

执行结果
传参不是字典类型,请重新设置!

相关文章

网友评论

      本文标题:python3 字典dict的综合运用(这是一段意外写出来的程序

      本文链接:https://www.haomeiwen.com/subject/eclivktx.html