day10-函数进阶

01函数的参数

  • 1.位置参数和关键字参数

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

    • 1)位置参数:调用函数的时候让实参和形参在位置上意义对应
    • 2)关键字参数:调用函数的时候以’形参名=值‘的形式确定形参对应的实参
    • 3)位置参数和关键字参数混用:位置参数必须在关键字参数前面,同时必须保证每个参数都会有一次赋值
    def func1(x, y, z):
        print(f'x:{x},y:{y},z:{z}')
    
    # 位置参数
    func1(10, 20, 30)
    func1(10, 30, 20)
    
    #关键字参数
    func1(x=10, y=20, z=30)
    func1(x=10, z=20, y=30)
    
    # 混用
    func1(10, 20, z=30)
    func1(10, z=20, y=30)
    
  • 2.参数默认值

  • 定义函数的时候可以直接在形参后面用=给形参赋默认值

  • 有默认值的参数在调用的时候可以不用传参

  • 如果有的参数有默认值,有的没有,有默认值的参数必须放在没有默认值参数的后面

    def func2(x=10,y=20,z=30):
        print(f'x:{x},y:{y},z:{z}')
    
    func2()      # x:10,y:20,z:30
    func2(100)   # x:100,y:20,z:30
    func2(z=300)  # x:10,y:20,z:300
    
    
    # def fun3(x=10,y=20,z):    # SyntaxError: non-default argument follows default argument
    #     print(f'x:{x},y:{y},z:{z}')
    
    
    def fun3(z,x=10,y=20):
        print(f'x:{x},y:{y},z:{z}')
    fun3(1000)   # x:10,y:20,z:1000
    # fun3(x=400)   # TypeError: fun3() missing 1 required positional argument: 'z'
    
    print(10,20,end='\n',sep=',')
    
    print(10,20,sep=',',end='\n')
    
  • 3.参数类型说明

    • 无默认值参数的类型说明 - :类型名
    • 有默认值的参数,默认值的类型就是参数对应的类型
    def func4(x:str, y=''):
        x.split('\n')
        y.replace('you','me')
    
  • 4.不定长参数

    • 1)带的不定长参数:
      • 在某个形参前加*,那么这个形参就是不定长参数,它可以接受任意多个参数
      • 带*的参数本质就是一个元组,对应的实参是元组中的元组中的元素
      • 注意:**的不定长参数对应的实参必须用位置参数传参
    • 2)带*的不定长参数:
      • 在某个形参前加*,那么这个形参就是一个不定长参数,它可以接收任意多个实参
      • 带*的参数本质就是一个字典,对应的关键字参数就是字典中的键值对
      • 注意:*的不定长参数对应的实参必须使用关键字参数传参
# sum1(10,20)
# sum1(10,20,30)

print(10)
print(10,20)

def func5(*x):
    print(x)

# func5()  # TypeError: func5() missing 1 required positional argument: 'x'
func5()  # 不会报错       # ()空的元组
func5(10,20,30)    # 不会报错   # (10, 20, 30) 元组

# func5(x=10)  # TypeError: func5() got an unexpected keyword argument 'x'
  • 1)定长参数在*的不定长参数之前,定长和不定长都使用位置参数传参

    def func6(char,x,*num):
        print(f'char:{char},nums:{num},x:{x}')
    
    func6('+',10)  # char:+,nums:(),x:10
    func6('=',12,34,45)   # char:=,nums:(34, 45),x:12
    
  • 2)定长在*的不定长参数后面,*后面的定长参数必须是用关键字参数传参

    def func7(*nums,char):
        print(f'nums:{nums},char:{char}')
    func7(10,20,char='*')   # nums:(10, 20),char:*
    
    def func8(*,a,b,c):
        print(f'a:{a},b:{b},c:{c}')
    func8(a=10,b=20,c=30)   # a:10,b:20,c:30
    
    
    # def func9(*a,*b):   # 只能有一个不定长参数
    #     pass
    
  • 3).**的使用

    def func9(**x):
        print(x)
    func9()  # {}
    func9(x=10)   # {'x': 10}
    func9(a=10,b=20)   # {'a': 10, 'b': 20}
    func9(m=1,n=2,a=3,b=100)  # {'m': 1, 'n': 2, 'a': 3, 'b': 100}
    
    
    # 定长参数在**的不定长前,定长既可以用位置参数,也可以用关键字参数
    def func10(x,**y):
        print(f'x:{x},y:{y}')
    
    func10(10,a=10,b=20)   # x:10,y:{'a': 10, 'b': 20}
    func10(x=100,a=1,b=2)  # x:100,y:{'a': 1, 'b': 2}
    
  • 5)定长参数不能放在**对应不定长参数后面

# def func11(**x,y):
#     pass
  • 6)带的不定长参数可以和带**的不定长参数一起用,带的必须放在带**的前面

    • 既可以传位置参数,也可以传关键词参数
    def func11(*args,**kwargs):
        pass
    func11()
    func11(10)
    func11(10,29,9)
    func11(a=2)
    func11(a=10,b=2)
    func11(1,2,x=10)
    
    
    def test(fn):
        def new_fn(*args,**kwargs):
            pass
        return new_fn
    

02 函数返回值

  • 1.返回值

  • 返回值的作用就是将函数内部的数据传递到函数外部

  • 2.怎么确定函数返回值 — 怎么将函数内容的数据传送到外部

    • 在函数体中用return关键字来返回返回值(一个函数只有一个返回值)
    • 什么时候需要返回值,如果函数的功能产生了新的数据,将新的数据返回
  • 3.怎么获取函数返回值

  • 获取函数调用表达式的值就是获取函数返回值

  • 函数调用表达式 -调用函数的语句

  • 函数调用表达式的值就是函数返回值,函数返回值能做的事情,韩式调用表达式都可以做

def sum2(num1,num2):
    return num1 + num2
print(sum2(10,20))

result = sum2(10,20)
print(result)
  • 4.函数调用过程

    """
    第一步:回到函数定义的位置
    第二步:传参(用实参给形参赋值,这个时候要保证每个参数都有值)
    第三步:执行函数体
    第四步:执行完函数体的时候确定函数返回值
           (看执行函数体的时候有没有遇到return,如果遇到return ,return后面的值是什么,函数返回值就是什么
           并且在遇到return的时候函数直接结束。如果没有遇到return,函数返回值是None)
    第五步:回到函数调用的位置(这个时候函数调用表达式的值才是函数的返回值)
           
    """
    
    
    def func4():
        return 10,20
    print(func4())  # (10, 20)  # 返回一个元组
    
# 练习:写一个函数通过指定方法来计算多个的结果
# operation('+', 10, 20, 30)  -> 求: 10+20+30
# operation('*', 3, 4, 5, 6)   -> 求 3*4*5*6
# operation('-', 10, 3, 4)  -> 求: 10-3-4
# operation('/', 19, 2)  -> 求 19/2
def operation(operation:str,*num):
    if not num or operation not in ('+','-','*','/'):
        return False
    if operation == '+':
        s1 = num[0]
        for x in num[1:]:
            s1 += x
        return s1
    elif operation == '*':
        s2 = num[0]
        for x in num[1:]:
            s2 *= x
        return s2
    elif operation == '-':
        s3 = num[0]
        for x in num[1:]:
            s3 -= x
        return s3
    elif operation == '/':
        s4 = num[0]
        for x in num[1:]:
            s4 /= x
        return s4


print(operation('+', 10, 20, 30))
print(operation('*', 3, 4, 5, 6))
print(operation('-', 10, 3, 4))
print(operation('/', 19, 2))

03变量的作用域

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

    • 根据变量的作用域不同,将变量分为全局变量和局部变量两种

    • 2.全局变量

      """
      没有定义在函数里面和类里面的变量就是全局变量;
      全局变量的作用域:从定义开始到程序结束
      """
      
      a = 10
      for x in range(5):
          b = 20
      
      # a,x,b都是全局变量
      # print(b)
      
      
      def func1():
          print(f'函数里面a:{a},b:{b},x{x}')
      func1()
      
    • 3.局部变量

    """
    定义在函数里面的变量称为局部变量(形参也是局部变量)
    类里面的变量称为属性
    局部变量的作用域:从定义开始到函数结束
    """
    
    def func2(c=3):
        d=100
    func2()
    # print(f'函数外部c:{c},d{d}')
    
    • 4.函数调用过程就是压栈的过程

      • 调用函数的时候,系统自动在栈区间为这个函数创建一个临时的栈区间,用来保存在函数中产生的数据(局部变量)
      • 当函数调用结束,这个临时栈区间会自动释放(释放之前会将返回值传递到临时栈区间的外部)
      1. global
      """
      在函数中修改一个全局变量的值或者在函数定义一个全局变量
      
      global 变量名
      使用变量
      """
      
      num = 30
      m = 10
      def func3():
          num = 40 # 不是在修改全局变量num的值,而是定义了一个新的局部变量
          print(f'函数内部num:{num}')
      
          global m
          m= 200
          print(f'函数内部m:{m}')
      
      func3()
      print(f'函数外部num:{num}')
      print(f'函数外部m:{m}')
      

作业

  1. 编写一个函数,计算一个整数的各位数的平方和
例如: sum1(12) -> 51的平方加上2的平方)    sum1(123) -> 14
def func1(num):
    t = 0
    while num:
        t += (num % 10) ** 2
        num //= 10
    return t
print(func1(12))
print(func1(123))
  1. 写一个函数,求一个数字列表中绝对值最大的元素
例如:nums = [-23, 100, 89, -56, -234, 123], 最大值是:-234
def func2(l:list):
    max1 = l[0]
    index1 = 0
    for i in range(len(l)):
        if abs(l[i]) >= abs(max1):
            max1 = abs4(l[i])
            index1 = i
    return l[index1]

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

    def func3(l, s:str):
        str1 = ''
        for x in l[:-1]:
            str1 = str1 + x + s
        return str1+l[-1]
    # str2 = ['hello','world','you','1123']
    # str2='frgg'
    str2 = ['hello']
    print(func3(str2,'+'))
    
  2. 写一个函数实现列表extend的功能,将指定序列中的元素全部添加到指定列表中

    def func4(l:list,s1):
        for x in s1:
            l.append(x)
    str1=[1,2,3]
    str2='sdw'
    func4(str1,str2)
    print(str1)
    
  3. 写一个函数实现简易计算器的功能:输入第一个数字,输入运算符,输入第二个数字,计算结果。

执行过程1:
计算器:
>10
>+
>20
=30

执行过程1:
计算器:
>10
>x
>20
=200

....
def operation(operation:str,*num):
    if not num or operation not in ('+','-','*','/'):
        return False
    if operation == '+':
        s1 = num[0]
        for x in num[1:]:
            s1 += x
        return s1
    elif operation == '*':
        s2 = num[0]
        for x in num[1:]:
            s2 *= x
        return s2
    elif operation == '-':
        s3 = num[0]
        for x in num[1:]:
            s3 -= x
        return s3
    elif operation == '/':
        s4 = num[0]
        for x in num[1:]:
            s4 /= x
        return s4



num1 = float(input('>'))
s = input('>')
num2 = float(input('>'))
print('=',operation(s,num1,num2))
  1. 已经列表points中保存的是每个点的坐标(坐标是用元组表示的,第一个值是x坐标,第二个值是y坐标)
points = [
  (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)
]

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

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

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

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

points = [(10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)]

def func1(l:list):
    max1 = l[0][-1]
    index = 0
    for i in range(len(l)):
        if l[i][-1] >= max1:
            max1 = l[i][-1]
            index = i
    return l[index]

print('列表中y坐标最大的点',func1(points))
def func2(l:list):
    index = 0
    min1 = l[0][0]
    for i in range(len(l)):
        if l[i][0] <= min1:
            min1 = l[i][0]
            index = i
    return l[index]

print('列表中x坐标最小的点',func2(points))

import math
def func3(l:list):
    max1 = 0
    index = 0
    for i in range(len(l)):
        d = math.sqrt(l[i][0]**2 + l[i][-1]**2)
        if d >= max1:
            max1 = d
            index = i
    return l[index]
print(func3(points))



def x_dist(list1: list):
    res = []
    # set([abs(x[-1]) for x in list1])
    list2 = sorted(set([abs(x[-1]) for x in list1]), reverse=True)
    for value in list2:
        res.extend([x for x in list1 if x[-1] in [value, -value]])
    return res

# f2
points.sort(reverse=True, key=lambda x: abs(x[-1]))

print(points)

# 列表中y坐标最大的点 (0, 100)
# 列表中x坐标最小的点 (-10, 20)
# (30, -100)
# [(0, 100), (30, -100), (20, 30), (10, 20), (-10, 20)]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值