day10-函数以及作用域

day10

总结

1. 函数

  • 位置参数和关键字参数(根据实参的提供的不同将实参分为位置参数和关键字参数)

    """
    1) 位置参数:调用函数的时候让实参和形参在位置上一一对应
    2) 关键字参数:调用函数的时候以’形参名=值‘的形式确定形参对应的实参。
    3) 位置关键字和关键字参数混用: 位置参数必须在关键字参数前面,必须保证每个参数都会有一次赋值
    """
    
    
    def func1(x, y, z):
        print(f'x:{x},y:{y},z:{z}')
    
    
    # 位置参数
    func1(10, 20, 30)  # x:10,y:20,z:30
    
    # 关键字参数
    func1(x=10, z=20, y=30)  # x:10,y:30,z:20
    func1(20, z=100, y=200)  # x:20,y:200,z:100
    
    
    # func1(x=100, 20, z=400)     # SyntaxError: positional argument follows keyword argument
    
  • 参数默认值 - 定义函数的时候可以直接在形参后面用=给形参赋默认值

    # 有默认值的参数在调用的时候可以不用传参
    # 如果有的参数有默认值有的没有,有默认值的参数必须放在没有默认值的后面
    # def func3(x=100, y):        # SyntaxError: non-default argument follows default argument
    #     print(f'x:{x}, y:{y}')
    
    
    def func2(x, y, z=100, i=200, j=400):
        print(f"x:{x}, y:{y}, z:{z}, j:{j}, i:{i}")
    
    
    func2(10, 40)  # x:10, y:40, z:100, j:400, i:200
    func2(10, 30, i=1000)  # x:10, y:30, z:100, j:400, i:1000
    print(10, 20, end='\n', sep=',')  # 10,20
    
  • 参数类型说明 - 仅对参数类型进行说明,不做约束

    # 无默认值参数的类型说明   -   形参:  类型名-例如:int
    # 有默认值的参数,默认值的类型就是参数对应的类型
    def func4(x: str, y=1) -> None:
        pass
        print(f'str:{x}, y:{y}')
    
    
    func4([1, 2, 3], 2)  # str:[1, 2, 3], y:2
    
  • 不定长参数

    """
    1) 带*的不定长参数:在某个形参前加*,那么这个形参就是一个不定长形参,它可以接收任意多个实参
                      带*的本质就是一个元组,对应的实参是元组中的元素
        注意:带*的不定长参数对应的实参必须用位置参数传参,
        带*号前传入参数只能用位置参数,带*号后传入传入参数只能用关键字参数,所以默认不带默认值的形参放在带*号的形参前,有默认的形参写在带*号的形参之后
    
    2) 带**的不定长参数:在某个形参前加**,那么这个形参就是一个不定长参数,它可以接受任意多个数的参数
        带**的参数本质就是一个字典,对应的关键字参数就是字典中的键值对
        注意:**的不定长参数对应的参数必须用关键字传参
    """
    # 定长参数在*的不定长参数前,定长和不定长都适用于位置参数传参
    
    
    def func5(y=10, *x, z):
        pass
        print(f'y:{y}, x:{x}, z:{z}, type(x):{type(x)}')
    
    
    # func5(x=(100, 30))      # TypeError: func5() got an unexpected keyword argument 'x'
    # func5()
    func5(19, 38, 25, 100, 2343, z=10)      # y:19, x:(38, 25, 100, 2343), z:10, type(x):<class 'tuple'>
    # func5(19, 38, 25, 100, 2343, z=10, y=120)   # TypeError: func5() got multiple values for argument 'y'
    # func5(19, 38, 25, 100, 2343, 10)        # TypeError: func5() missing 1 required keyword-only argument: 'z'
    
    
    def func6(z, *x):
        print(f'z:{z}, x:{x}')
    
    
    def func7(x, y, z=10):
        print(f"x:{x}, y:{y}, z:{z}")
    
    
    print('===================================================')
    
    
    # 3) **的使用
    def func9(**x):
        pass
        print(f"x:{x}")
    
    
    func9(x=10, a=10, b=12)     # x:{'x': 10, 'a': 10, 'b': 12}
    
    
    # 4) 定长参数在**的不定长前,定长既可以用位置参数也可以用关键字参数
    def func10(x, **y,):
        pass
        print(f"x:{x}, y:{y}")
    
    
    func10(x=2, a=10)       # x:2, y:{'a': 10}
    func10(2, a=10)         # x:2, y:{'a': 10}
    
    
    # 5) 定长参数不能放在**的不定长参数后面
    # def func11(**y, *y):        # SyntaxError: invalid syntax
    #     pass
    
    
    # 6) 带*的不定长参数和带**的不定长参数可以一起使用,带*的必须放在带**的前面
    def func11(*args, **kwargs):
        pass
        print(args, kwargs)
    
    
    func11()    # () {}
    func11(1, 2, 3)     # (1, 2, 3) {}
    func11(a=10)        # () {'a': 10}
    
  • 返回值(返回值的作用就是将函数内部的数据传递到函数外部)

    # 在函数体中用return关键字来返回返回值(一个函数只有一个返回值)
    # 什么时候需要返回值;如果函数的功能产生了新的数据,将新的数据返回
    
    
    def sum2(num1=0, num2=0):
        return num2 + num1
    
  • 字母确定函数返回值 - 怎么将函数内部的数据传递到外部

  • 怎么获取函数返回值

    # 获取函数调用表达式的值就是获取函数返回值
    # 函数调用表达值   -   调用函数的语句
    # 函数调用表达式的值就是函数返回值,函数返回值能做的事,函数表达式都可以做
    result = sum2(10, 30)  # 40
    print(result)
    print(sum2(10, 20))  # 30
    a = result + 10
    a = sum2(10, 30) + 10
    
    
    def func1():
        return [10, 20]
    
    
    print([10, 20][-1])  # 20
    print(func1()[-1])  # 20
    list1 = func1()
    list1.append('hello')
    list1.insert(0, 'hhhh')
    list1.extend([10, 20, 30])
    del list1[0]
    list1.remove('hello')
    list1.pop(3)
    list1[0] = 100
    print(list1)  # [100, 20, 10, 30]
    
    
    def func2():
        return 10, 20
    
    
    for x in func2():
        print(x)
    print(len(func2()))
    print(max(func2()))
    
  • 函数调用过程

    """
    第一步:回到函数定义的位置
    第二步:传参(用实参给形参赋值,这个时候要保证每个参数都有值)
    第三步:执行函数体
    第四步:执行完函数体,确认返回值
        (看执行函数体的时候有没有遇到returnj, 如果遇到return,return后面的值是什么,函数的返回值就是什么,并且在遇到
        return的时候函数直接结束。如果没有遇到return,函数返回值就是None)
    第五步:回到函数调用的位置(这个时候函数调用表达式的值才是函数的返回值)
    """
    
    
    def func3():
        print('---------')
        return
        return 100
        print('==========')
        print('+++++++')
    
    
    print(func3())
    
    
    def func4():
        return 10, 20
    
    
    print(func4())
    
    
    # 练习:写一个函数通过指定方式来计算多个数的结果
    # operation('+', 10, 20, 30)    -> 求: 10+20+30
    # operation('*', 3, 4, 5, 6)    -> 求:3*4*5*6
    
    def my_operation(operator: str, *nums) -> (int, None):
        if nums:
            if operator == '+':
                sum1 = 0
                for num in nums:
                    sum1 += num
                return sum1
                # return sum(nums)
    
            elif operator == '*':
                res = 1
                for num in nums:
                    res *= num
                return res
    
            elif operator == '-':
                res = nums[0]
                for num in nums[1:]:
                    res -= num
                return res
    
            elif operator == '/':
                dividend = nums[0]
                for divisor in nums[1:]:
                    dividend /= divisor
                return dividend
    
    
    res = my_operation('/', 1, 3, 4, 5)
    print(res)      # 0.016666666666666666
    res = my_operation('-', 10, 32, 43, 1)
    print(res)      # -66
    res = my_operation('+', 1, 2, 3, 4, 5)
    print(res)      # 15
    res = my_operation('*', 13, 43, 23, 5, 2)
    print(res)      # 128570
    
    
    def odevity(num: int):
        if num % 2:
            return '奇数'
        return '偶数'
    

2. 作用域

  • 变量的作用域 - 已经定义过的变量能使用范围

  • 全局变量

    """
    没用定义在函数里或类里面的变量就是全局变量;
    全局变量的作用域:从定义开始到程序结束的任何位置都可以使用
    """
    # a, b, x都是全局变量
    a = 10
    for x in range(10):     # 全部变量
        b = x
    print(a, b, x)  # 10 9 9
    
    
    def func1():
        print(a, b, x)
    
    
    func1()     # 10 9 9
    
  • 局部变量

"""
定义在函数里的变量就是局部变量(形参也是局部变量)
局部变量的作用域:从定义开始到函数结束
"""


# c, d都是局部变量
def func2(c=3):
    d = 100


func2()
  • 函数调用过程就是压栈的过程

    """
    调用函数的时候,系统会自动在栈区间为这个函数创建一个临时栈区间,用来保持在函数中产生的数据(局部变量)。
    当函数调用结束,这个临时栈区间会自动释放(释放之前会将返回值传递到临时栈区间的外部)。
    """
    
  • global - 在函数内部

    """
    在函数中修改一个全局变量的值或者在函数定义一个全局变量
    
    语法:
    gloabl 变量
    使用变量
    """
    
    
    num = 30
    m = 100
    
    
    def func4():
        num = 40        # 不是在修改全局变量num的值,而是定义一个新的局部变量
        print(f"函数内部num:{num}")     # 函数内部num:40
    
        global m
        m = 200     # 在函数中修改一个全局变量的值,需要先用global进行说明
        print(f"函数内部m:{m}")     # 函数内部m:200
    
        global n
        n = 'abc'
    
    
    func4()
    print(f"函数外部num:{num}")     # 函数外部num:30
    print(f"函数外部m:{m}")     # 函数外部m:200
    print(f"函数外n:{n}")      # 函数外n:abc
    

作业

  1. 编写一个函数,计算一个整数的各位数的平方和
例如: sum1(12) -> 51的平方加上2的平方)    sum1(123) -> 14
def sum1(num: int) -> int:
    """
    计算一个整数的各位数的平方和
    :param num:  需要计算的整数
    :return:  该数的各位数的平方和
    """
    if type(num) != int:
        return None
    res = 0
    if num >= 0:
        for x in str(num):
            res += int(x)**2
    else:
        for x in str(num)[1:]:
            res += int(x) ** 2
    return res


print(sum1(-123))		# 14
  1. 写一个函数,求一个数字列表中绝对值最大的元素
# 例如:nums = [-23, 100, 89, -56, -234, 123], 最大值是:-234

def abs_max_list(list1: list):
    """
    求一个数字列表中绝对值最大的元素
    :param list1:   传入数字列表
    :return:    列表中元素绝对值最大对应的元素
    """
    if type(list1) != list or not list1:
        return None
    # value = list1[0]
    abs_max = abs(list1[0])
    for x in list1[1:]:
        if abs_max < abs(x):
            abs_max = abs(x)
            # value = x
    # return value
    return [x for x in list1 if x in [abs_max, -abs_max]]


print(abs_max_list([-23, 100, 89, -56, -234, 123]))   # -234
  1. 编写函数实现字符串join方法的功能,将指定序列中的元素通过指定字符串合并成一个新的字符串

    def sequence_join(sequence, joinstr: str):
        """
        将指定序列中的元素通过指定字符串合并成一个新的字符串
        :param sequence:    需要拼接的序列
        :param joinstr:     拼接字符串
        :return:    新字符串
        """
        if not sequence:
        	return None
        res = ''
        for x in sequence[:-1]:
            res += str(x) + joinstr
        res += str(sequence[-1])	
        return res
    
    
    print(sequence_join([-23, 100, 89, -56, -234, 123], '+'))       # -23+100+89+-56+-234+123
    
  2. 写一个函数实现列表extend的功能,将指定序列中的元素全部添加到指定列表中

    def list_extend(list1: list, sequence):
        """
        将指定序列中的元素全部添加到指定列表中
        :param list1:   指定列表
        :param sequence:    指定序列
        :return:    None
        """
        for x in sequence:
            list1.append(x)
    
    
    list1 = [-23, 100, 89, -56, -234, 123]
    list_extend(list1, (12, 110))
    print(list1)
    
  3. 写一个函数实现简易计算器的功能:输入第一个数字,输入运算符,输入第二个数字,计算结果。

    执行过程1:
    计算器:
    >10
    >+
    >20
    =30
    
    执行过程1:
    计算器:
    >10
    >x
    >20
    =200
    
    ....
    
    def calculator():
        """
        简易计算器
        :return:    None
        """
        num1 = float(input('>'))
        if num1 % 1 == 0:
            num1 = int(num1)
        operator = input('>')
        num2 = float(input('>'))
        if num2 % 1 == 0:
            num2 = int(num2)
        if operator == '+':
            print(f'={num1 + num2}')
        elif operator == '-':
            print(f'={num1 - num2}')
        elif operator == 'x' or operator == 'X':
            print(f'={num1 * num2}')
        elif operator == '/':
            print(f'={num1 / num2}')
        elif operator == '%':
            print(f'={num1 % num2}')
        else:
            print('暂时无法进行该运算符的计算,请尽情期待下一个版本!')
    
    
    calculator()
    
  4. 已经列表points中保存的是每个点的坐标(坐标是用元组表示的,第一个值是x坐标,第二个值是y坐标)

    points = [
      (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)
    ]
    
    
    def get_max_y_from_points(points: list):
        """
        获取列表中y坐标最大的点
        :param points:  要进行操作的坐标列表
        :return: 列表中y坐标最大的点
        """
        if not points:
            return None
        max_y_point = points[0]
        for x, y in points[1:]:
            if max_y_point[-1] < y:
                max_y_point = (x, y)
        return max_y_point
    
    
    def get_min_x_from_points(points: list):
        """
        获取列表中x坐标最小的点
        :param points:  要进行操作的坐标列表
        :return:    列表中x坐标最小的点
        """
        if not points:
            return None
        min_x_point = points[0]
        for x, y in points[1:]:
            if min_x_point[0] > x:
                min_x_point = (x, y)
        return min_x_point
    
    
    def get_max_distance_from_points(points: list):
        """
        获取列表中距离原点最远的点
        :param points:  要进行操作的坐标列表
        :return:    列表中距离原点最远的点
        """
        if not points:
            return None
        max_distance_point = points[0]
        max_distance_square = max_distance_point[0]**2 + max_distance_point[-1]**2
        for point in points:
            if max_distance_square < point[0]**2 + point[-1]**2:
                max_distance_point = point
        return max_distance_point
    
    
    def points_sort_by_x_distance(points: list):
        """
        将点按照点到x轴的距离大小从大到小排序
        :param points:  要进行操作的坐标列表
        :return:    按照点到x轴的距离大小从大到小排序后的列表
        """
        if not points:
            return None
        new_points = []
        list1 = sorted({abs(x[-1]) for x in points}, reverse=True)
        for value in list1:
            new_points.extend([x for x in points if x[-1] in [value, -value]])
        return new_points
    

    1)获取列表中y坐标最大的点

    max_y_point = get_max_y_from_points(points)  
    max_y_points = [x for x in points if x[-1] == max_y_point[-1]]
    print(max_y_points)
    

    2)获取列表中x坐标最小的点

    min_x_point = get_min_x_from_points(points)
    min_x_points = [x for x in points if x[0] == min_x_point[0]]
    print(min_x_points)
    

    3)获取列表中距离原点最远的点

    max_distance_point = get_max_distance_from_points(points)
    max_distance_points = [x for x in points if x[0]**2 + x[-1]**2 == max_distance_point[0]**2 + max_distance_point[-1]**2]
    print(max_distance_points)
    

    4)将点按照点到x轴的距离大小从大到小排序

    # 方法一
    points = points_sort_by_x_distance(points)
    # 方法二
    points.sort(reverse=True, key=lambda x: abs(x[-1]))
    print(points)
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值