• Python基础之函数


    一、函数定义

      

      

    二、作用:提高代码的可重用性和可维护性(代码层次结构更清晰)。

    三、函数返回值:

      

    四、实例

      

    # 定义根据月份,判断季节的方法.
    def get_season(month):
        if month < 1 or month > 12:
            return "输入有误"
        if month <= 3:
            return "春天"
        if month <= 6:
            return "夏天"
        if month <= 9:
            return "秋天"
        return "冬天"
    
    print(get_season(5))
    print(get_season(15))
    
    
    # 练习:定义检查列表是否具有相同元素的方法
    def is_repeating(list_target):
        for r in range(len(list_target) - 1):
            for c in range(r + 1, len(list_target)):
                if list_target[r] == list_target[c]:
                    return True # 退出方法(可以退出两层循环)
        return False
    re01 = is_repeating([3,44,5])
    re01 = is_repeating([3,44,5,44])
    print(re01)
    
    
    
    #练习:定义在控制台中显示直角三角形的函数
    def print_triangle(height,char):
        """
            打印三角型
        :param height: 三角形高度
        :param char: 组成三角型的字符
        :return:
        """
        for r in range(height):
            for c in range(r+1):
                print(char, end="")
            print()
    
    print_triangle(8,"*")
    print_triangle(5,"#")
    print_triangle(4,"?")
    
    
    # 练习:定义在控制台中显示矩形的函数 
    def print_rect(r_count,c_count,char):
        for r in range(r_count):#      0        1        2
            for c in range(c_count):#01234    01234    01234
                print(char,end = "") # 在一行输出
            print() # 换行
    
    print_rect(2,3,"*")
    print_rect(5,2,"#")
    # 参数:变量
    #     函数调用者  告诉 函数定义者的信息

     

    # 1. 参照下列代码,定义判断是否是奇数的方法.
    #     number = int(input("请输入整数:"))
    #     if number % 2 == 1:
    #         print("奇数")
    #     else:
    #         print("偶数")
    
    def is_uneven(number):
        # 方法1:传统方法
        # if number % 2 == 1:
        #     return True
        # else:
        #     return False
        # 方法2:条件表达式
        # return True if number % 2 == 1 else False
        # 方法3:bool表达式
        return number % 2 == 1
    
    re = is_uneven(6)
    print(re)
    # 2.参照下列代码,定义根据月份返回天数的方法.
    #   要求:考虑2月,如果是闰年返回29天,否则返回28天.
    #     month = int(input("请输入月份:"))
    #     if month < 1 or month > 12:
    #         print("输入有误")
    #     elif month == 2:
    #         print("28天")
    #     elif month == 4 or month == 6 or month == 9 or month == 11:
    #         print("30天")
    #     else:
    #         print("31天")
    
    # 向外返回的结果return,其类型应该统一.
    # 方法1:传统方法:
    # def get_day_by_month(year,month):
    #     if month < 1 or month > 12:
    #         return 0
    #     elif month == 2:
    #         if year % 4 == 0 and year % 100 != 0 or year % 400 ==0:
    #             return 29
    #         else:
    #             return 28
    #     elif month == 4 or month == 6 or month == 9 or month == 11:
    #         return 30
    #     else:
    #         return 31
    
    
    
    # 方法2:定义函数嵌套法+条件表达式精简代码
    
    def is_leap_year(year):
        return year % 4 == 0 and year % 100 != 0 or year % 400 == 0
    
    def get_day_by_month(year, month):
        if month < 1 or month > 12:
            return 0
        if month == 2:
            return 29 if is_leap_year(year) else 28
        if month in (4, 6, 9, 11):
            return 30
        return 31
    
    day = get_day_by_month(2019,13)
    print(day)
    # 3.参照下列代码,定义获取最小值方法.
    #     min = list01[0]
    #     for i in range(1, len(list01)):
    #         # 发现更大的,则替换假设的.
    #         if min > list01[i]:
    #             min = list01[i]
    #     print(min)
    
    def get_min(list_target):
        min = list_target[0]
        for i in range(1, len(list_target)):
            if min > list_target[i]:
                min = list_target[i]
        return min
    
    
    min = get_min([2, 3, 45, 1, 9, 3])
    print(min)
    # 4. 定义函数,判断字符串中存在的中文字符数量.
    #     中文编码范围:0x4E00   ord(字符)    0x9FA5
    
    
    def get_chinese_char_count(str_target):
        count = 0
        for item in str_target:
            if 0x4E00 <= ord(item) <= 0x9FA5:
                count += 1
        return count
    
    
    count = get_chinese_char_count("a你sid你f好ln")
    print(count)
    # 5. 扩展练习(定义函数,返回指定范围内的素数)
    # 例如:1--100  
    
    
    # 方法1:传统方法
    # def get_prime(bengin,end):
    #     list_prime = []
    #     for number in range(bengin,end+1):
    #         if number < 2:
    #             pass
    #         else:
    #             for i in range(2, number):
    #                 if number % i == 0:
    #                     break  # 如果有结论了,就不需要在和后面的数字比较了
    #             else:
    #                 list_prime.append(number)
    #     return list_prime
    
    
    # 方法2:自定义函数相互之间嵌套法
    def get_prime(bengin, end):
        """
            生成指定范围内的所有素数
        :param bengin: 开始
        :param end: 结束
        :return: 范围内的所有素数
        """
        list_prime = []
        for number in range(bengin, end + 1):
            if is_prime(number):
                list_prime.append(number)
        return list_prime
    
    
    def is_prime(number):
        """
            判断是否为素数
        :param number: 需要判断的数
        :return: 是不是素数
        """
        if number < 2:
            return False # 不是素数
        # 判断能否被中间的数字整除
        for i in range(2, number):
            if number % i == 0:
                return False # 不是素数
        return True # 是素数
    
    
    primes = get_prime(5, 100)
    print(primes)
    
    primes = get_prime(-5, 50)
    print(primes)

     五、函数重构代码思想

      

      案例:未重构前代码如下

      

    shang_pin_info = {
        101: {"name": "屠龙刀", "price": 10000},
        102: {"name": "倚天剑", "price": 10000},
        103: {"name": "九阴白骨爪", "price": 8000},
        104: {"name": "九阳神功", "price": 9000},
        105: {"name": "降龙十八掌", "price": 8000},
        106: {"name": "乾坤大挪移", "price": 10000}
    }
    
    ding_dan = []
    
    
    def gou_wu():
        """
            购物
        :return:  
        """
        while True:
            item = input("1键购买,2键结算。")
            if item == "1":
                for key, value in shang_pin_info.items():
                    print("编号:%d,名称:%s,单价:%d。" % (key, value["name"], value["price"]))
                while True:
                    cid = int(input("请输入商品编号:"))
                    if cid in shang_pin_info:
                        break
                    else:
                        print("该商品不存在")
                count = int(input("请输入购买数量:"))
                ding_dan.append({"cid": cid, "count": count})
                print("添加到购物车。")
            elif item == "2":
                zong_jia = 0
                for item in ding_dan:
                    shang_pin = shang_pin_info[item["cid"]]
                    print("商品:%s,单价:%d,数量:%d." % (shang_pin["name"], shang_pin["price"], item["count"]))
                    zong_jia += shang_pin["price"] * item["count"]
                while True:
                    qian = float(input("总价%d元,请输入金额:" % zong_jia))
                    if qian >= zong_jia:
                        print("购买成功,找回:%d元。" % (qian - zong_jia))
                        ding_dan.clear()
                        break
                    else:
                        print("金额不足.")
    
    
    gou_wu()

        重构后代码如下:

        

    dict_commodity_info = {
        101: {"name": "屠龙刀", "price": 10000},
        102: {"name": "倚天剑", "price": 10000},
        103: {"name": "九阴白骨爪", "price": 8000},
        104: {"name": "九阳神功", "price": 9000},
        105: {"name": "降龙十八掌", "price": 8000},
        106: {"name": "乾坤大挪移", "price": 10000}
    }
    
    list_order = []
    
    
    def select_menu():
        """
            菜单选择 
        """
        while True:
            item = input("1键购买,2键结算。")
            if item == "1":
                buying()
            elif item == "2":
                settlement()
    
    def settlement():
        """
            结算
        :return:
        """
        print_order()
        total_price = get_total_price()
        pay(total_price)
    
    def pay(total_price):
        """
            支付
        :param total_price: 需要支付的价格
        :return:
        """
        while True:
            money = float(input("总价%d元,请输入金额:" % total_price))
            if money >= total_price:
                print("购买成功,找回:%d元。" % (money - total_price))
                list_order.clear()
                break
            else:
                print("金额不足.")
    
    
    def print_order():
        """
            打印订单
        :return:
        """
        for item in list_order:
            commodity = dict_commodity_info[item["cid"]]
            print("商品:%s,单价:%d,数量:%d." % (commodity["name"], commodity["price"], item["count"]))
    
    
    def get_total_price():
        """
            计算总价
        :return:
        """
        total_price = 0
        for item in list_order:
            commodity = dict_commodity_info[item["cid"]]
            total_price += commodity["price"] * item["count"]
        return total_price
    
    
    def buying():
        """
            购买
        :return:
        """
        print_commodity()
        order = create_order()
        list_order.append(order)
        print("添加到购物车。")
    
    
    def create_order():
        """
            创建订单
        :return:
        """
        while True:
            cid = int(input("请输入商品编号:"))
            if cid in dict_commodity_info:
                break
            else:
                print("该商品不存在")
        count = int(input("请输入购买数量:"))
        return {"cid": cid, "count": count}
    
    
    def print_commodity():
        """
            打印商品
        :return:
        """
        for key, value in dict_commodity_info.items():
            print("编号:%d,名称:%s,单价:%d。" % (key, value["name"], value["price"]))
    
    
    # 程序入口
    select_menu()

      注:虽然代码量变大了,但是在项目编程时,逻辑更清晰,维护更便捷

     

    六、函数内存图示例(即可变/不可变类型在传参时的区别)

          

        示例1:

        

    """
        内存图1.0
        不可变对象传参
    """
    
    
    def fun01(num01):
        num01 = 2
        print("num01:" + str(num01))# 2
    
    
    number01 = 1
    # 调用方法,在内存中开辟空间(栈帧)
    # 栈帧中定义该方法内部创建的变量
    # 方法执行完毕后,栈帧立即释放.
    fun01(number01)
    print("number01:" + str(number01))# 1

        

         示例2:

          

    """
        内存图2.0
        可变对象传参
    """
    
    def fun01(list_target):
        list_target[0] = 2
        print("list_target[0]:" + str(list_target[0]))
    
    
    list_number = [1,2]
    fun01(list_number)
    print("list_number:" + str(list_number[0]))

        

          示例3

          

    def fun01(a,b,c):
        a = 100
        # 修改的是列表对象,
        b[0] = 200
        # 修改的是栈帧中的变量
        c = 300
    
    num01 = 1
    list01 = [2]
    list02 = [3]
    fun01(num01,list01,list02)
    
    print(num01)#? 1
    print(list01)#? [200]
    print(list02)#? [3]

        

    七、2048核心算法:

      

    """
        2048 核心算法:降維
    """
    
    # 练习1:定义函数,将零元素移动到末尾
    # [2,0,2,0] --> [2,2,0,0]
    # [0,2,2,0]  --> [2,2,0,0]
    # [0,4,2,4]  --> [4,2,4,0]
    
    
    """ 方案1
    def zero_to_end(list_target):
        # 1.将传入的列表中非零元素,拷贝到新列表中.
        # [2, 0, 2, 0] --> [2,2] --> [2,2,0,0]
        # [0, 4, 2, 4]  -->[4, 2, 4] -->[4, 2, 4 ,0]
        # 2. 根据为零元素的数量,在新列表中添加零元素
        # [2, 0, 2, 0] --> [2,2]
        new_list = [item for item in list_target if item != 0]
        # [2, 2] --> [2,2,0,0]
        new_list += [0] * list_target.count(0)
        # 3. 将新列表中元素赋值给传入的列表
        list_target[:] = new_list
    """
    # 方案2
    def zero_to_end(list_target):
        # 从后往前判断,如果零元素,则删除,在末尾追加零元素
        # [2, 0, 2, 0] --> [2, 2]  --> [2, 2,0,0]
        for i in range(len(list_target) - 1, -1, -1):
            if list_target[i] == 0:
                del list_target[i]
                list_target.append(0)
    
    
    # list01 = [2, 0, 2, 0]
    # zero_to_end(list01)
    # print(list01)
    
    # 练习2:定义合并函数
    # [2,2,0,0] --> [4,0,0,0]
    # [2,0,2,0] --> [4,0,0,0]
    # [2,0,0,2] --> [4,0,0,0]
    # [2,2,2,0] --> [4,2,0,0]
    
    def merge(list_target):
        # [2,0,2,0] --> [2,2,0,0]       [2,2,2,0]
        zero_to_end(list_target)
        # [2,2,0,0] --> [4,0,0,0]       [4,0,2,0]
        for i in range(len(list_target) -1):
            # 相邻且相同
            if list_target[i] == list_target[i+1]:
                list_target[i] += list_target[i+1]
                list_target[i+1] = 0
        zero_to_end(list_target)# [4,0,2,0] --> [4,2,0,0]
    
    # list01 = [2,2,2,0]
    # merge(list01)
    # print(list01)
    
    # 练习3:将二维列表,以表格的格式显示在控制台中  
    list01 = [
        [2,0,0,2],
        [2,2,0,0],
        [2,0,4,4],
        [4,0,0,2],
    ]
    def print_map(map):
        for r in range(len(map)):
            for c in range(len(map[r])):
                print(map[r][c],end = " ")
            print()
    
    # print_map(list01)
    
    #练习4:定义向左移动函数.11:50
    """
        [2,0,0,2]           [4,0,0,0] 
        [2,2,0,0]           [4,0,0,0]
        [2,0,4,4]           [2,8,0,0]
        [4,0,0,2]           [4,2,0,0]
    """
    def move_left(map):
        # 获取第行
        for r in range(len(map)):
            # 从左往右获取行
            # 交给merge进行合并
            merge(map[r])
    
    def move_right(map):
        # 获取第行
        for r  in range(len(map)):
            # 从右往左获取行
            # 交给merge进行合并
            list_merge = map[r][::-1]
            merge(list_merge)
            map[r][::-1] = list_merge
    
    # 作业1:定义向上移动函数
    # 从上往下获取列
    # 交给合并方法
    # 还给原列
    
    # 作业2:定义向下移动函数
    # 从下往上获取列
    # 交给合并方法
    # 还给原列
    
    def move_up(list_target):
        list_merge = []
        for c in range(len(list_target[0])):
            for r in range(len(list_target)):
                list_merge.append(list_target[r][c])
            merge(list_merge)
            for r in range(len(list_target)):
                list_target[r][c] = list_merge[r]
            list_merge = []
    
    def move_down(list_target):
        list_merge = []
        for c in range(len(list_target[0])):
            for r in range(len(list_target) - 1, -1, -1):
                list_merge.append(list_target[r][c])
            merge(list_merge)
            for r in range(len(list_target)):
                list_target[r][c] = list_merge[3 - r]
            list_merge = []
    
    
    
    # move_left(list01)
    # move_right(list01)
    # move_up(list01)
    move_down(list01)
    print_map(list01)

        

  • 相关阅读:
    CountDownLatch demo演示裁判和选手赛跑
    @Async异步方法对异常的处理,从内层向外层抛出机制
    python3读csv文件,出现UnicodeDecodeError: 'utf8' codec can't decode byte 0xd0 in position 0: invalid con
    Python3 dict和str互转
    python批量读取excel csv文件插入mysql数据库
    dotnet 6 精细控制 HttpClient 网络请求超时
    读书笔记 为什么要有R5G6B5颜色格式
    dotnet 6 推荐一个可代替 .NET Remoting 的 IPC 库
    dotnet 6 通过 DOTNET_ROOT 让调起的应用的进程拿到共享的运行时文件夹
    记 Win8.1 某应用渲染抛出 OutOfMemoryException 异常及修复方法
  • 原文地址:https://www.cnblogs.com/yuxiangyang/p/10679088.html
Copyright © 2020-2023  润新知