深入解析Python 函数:让你的代码更简洁高效!

一、函数的定义与目的

1、函数的定义

函数是具有一定功能,并对其功能实现封装的代码。

2、函数的目的

函数的目的是为了提高代码的复用,减少代码的重复编写,增加代码的灵活性。

二、函数的相关术语

1、函数的声明

def  函数名():

        pass

def my_def():
    """
    这是一个自定义函数
    """
    print('函数体')

函数名的命名方式按照变量的命名规则

2、函数的调用

函数名()

# 函数调用
my_def()

3、形参和实参

形参在函数声明的小括号中。

实参在函数调用的小括号中。

函数的形参可以传入多次,函数的实参要和形参相对应,按照顺序赋值。

def wakeup(name, num):
    """
    这里写函数的功能
    :param name: 这里写每个函数的功能
    :param num:
    :return: 这里写返回值
    """
    for i in range(num):
        print(f'第{i+1}次,叫醒:{name}')
    print('*************')


wakeup('张三', 4)

4、函数的返回值

返回值可以是一个,也可以是多个。返回一个参数时,返回原类型,多个参数返回时,返回的是元组。

def fun():
    return True, 200

r = fun()
print(r, type(r))
# (True, 200) <class 'tuple'>

三、初试函数

1、自定义一个函数,求两个数中的最大值

def my_max(first, second):
    """
    这里写函数的功能
    :param first:第一个形参
    :param second: 第二个形参
    :return: 返回值
    """
    max_num = first if first > second else second
    return max_num


r = my_max(0.55, 3.14)
print(r)
print(my_max(8, 10))
# 3.14
# 10

2、封装一个函数 求从start到stop之间相度为step的质数对。

def zs_num(start, stop, step):
    # 方法二:控制结束:for i in range(start, stop - step+ 1):
    for i in range(start, stop + 1):
        for j in range(2, i):
            if i % j == 0:
                break
        else:
            # 方法一:控制stop
            if i + step < stop:
                for k in range(2, i + step):
                    if (i + step) % k == 0:
                        break
                else:
                    print(f'{i},{i + step}')

zs_num(2, 100, 6)

将是否为质数的模块写为函数

def is_prime(num):
    """
    判断是否是质数
    :param num: 传入要判断的参数
    :return:返回是否为质数
    """
    for j in range(2, num):
        if num % j == 0:
            # # 方法一:
            # break
            # 方法二:
            return False
    else:
        return True


def zs_num(start, stop, step):
    """
    求质数对
    :param start: 开始值
    :param stop: 结束值
    :param step: 步长
    :return: 返回质数对
    """
    result = []
    for i in range(start, stop - step + 1):
        # # 方法一:
        # if is_prime(i):
        #     if is_prime(i + step):
        # 方法二:
        if is_prime(i) and is_prime(i + step):
            result.append((i, i + step))
    return result


r = zs_num(2, 1000, 18)
print(r)

四、函数调试

1、步过F8: 跳过函数,执行下一步。

2、步入F7: 执行自己编写的函数。

系统自带函数不用自己调试。

3、步出shift+F8:跳出函数。

4、恢复F9: 跳到下一个断点。

def f2(a, b):
    print('f2开始执行')
    for i in range(5):
        print(f"f2中的循环第{i}次执行")
    value = a + b
    return value

def f1(a, b):
    print(a, b)
    print(f"打印最大值:{max(a, b)}")
    print('开始调用f1')
    r = f2(a, b)
    return f"返回f1的结果:{r}"

r1 = f1(10, 20)
print(r1)

# 10 20
# 打印最大值:20
# 开始调用f1
# f2开始执行
# f2中的循环第0次执行
# f2中的循环第1次执行
# f2中的循环第2次执行
# f2中的循环第3次执行
# f2中的循环第4次执行
# 返回f1的结果:30

五、函数变量的作用域

1、函数内可调用外部变量————外部变量需要定义在调用前。

(1)、定义在函数内的变量,函数外不可以使用(函数外不能调用函数内的m,a)
def f1(m):
    a = 10
    print(m)
    m = a + 2
    c = a + b
    print(c)
    return m



# 定义在函数内的变量,函数外不可以使用(函数外不能调用函数内的m,a)
b = 12
# 定义在函数外的变量,函数内可以使用,不可以放在执行后
print(f1(5))
# 5
# 22
# 12
(2)、函数内定义的变量与函数外定义的变量重名,也只是有一个新的内存空间 。
  •  函数内对于外部变量,不能先获取,后赋值/使用
a = 10
print(id(a))
def f1():
    # 函数内对于外部变量,不能先获取,后赋值/使用
    # 如:
    # print(a)
    # a = 25

    # 函数内定义的变量与函数外定义的变量重名,也只是有一个新的内存空间
    a = 20
    return a, id(a)

print(id(a))
print(f1())
# 140729842000968
# 140729842000968
#(20, 140729842001288)

2、若改变外部变量,需要添加global关键字。

  • global 关键字,可以在函数内部修改函数外部的变量
def f1():
    # print(f"函数内部,没使用global之前:{a}, {id(a)}")
    # 声明全局变量之前不可调用原来的外部变量
    # 调用全局变量也要在声明之后
    global a
    print(f"函数内部,没使用global之前:{a}, {id(a)}")
    a = 20
    print(f"内部,使用global:{a}, {id(a)}")


f1()
print(f"函数执行完之后,外部:{a}, {id(a)}")

# 执行前,外部:10, 140730276832328
# 函数内部,没使用global之前:10, 140730276832328
# 内部,使用global:20, 140730276832648
# 函数执行完之后,外部:20, 140730276832648

3、不推荐在循环外部使用循环内部的局部变量。

五、函数的参数

  • 一个形参只能赋值一次,不能既有位置参数的赋值,又有关键字参数的赋值
  • 没有关键字的参数,必须有实参传入

1、位置参数

按照位置依次赋值。

def my_fun(a, b, c):
    print(a, b, c)


my_fun(1, 2, 3)
# 1 2 3

2、默认参数

def f1(a, b, c=200):
     print(a, b, c)


f1(10, 20, 30)
f1(5, 6)
# 10 20 30
# 5 6 200
(1)、默认值的例子:print(sep = " ", end = "\n")中有默认以空格分割,以换行结尾。
print(1, 2, 3, 4, 5, sep=" ", end="\n")
print(1, 2, 3, 4, 5, sep="+", end="\n")
# 1 2 3 4 5
# 1+2+3+4+5
(2)、默认参数写在最后,且可以有多个。
(3)、实参给默认参数赋值时,用实参给的值;不给时,使用默认值即可。
def f1(a, b, c=0, d='默认值'):
    print(a, b, c, d)


f1(1, 2, 3)
f1(6, 7, 8, '实参赋值时,会使用实参')
# 1 2 3 默认值
# 6 7 8 实参赋值时,会使用实参

3、关键字参数

(1)、关键字参数允许通过名称指定函数参数的值,而不是按照它们在函数定义中的顺序传递参数。
(2)、关键字参数必须跟随在位置参数后面。
def f1(a, b, c=6):
    print(a, b, c)


# 关键字参数必须跟随在位置参数后面
f1(b=7, a=8, c=9)
# 8 7 9
(3)、还可以在函数定义时指定某些参数的默认值,使其成为可选参数。
def greet(name, message='hello'):
    print(f'{message},{name}!')


greet(name='Alice')
greet(name='Bob', message='Hi')
# hello,Alice!
# Hi,Bob!

4、可变元组

(1)、用*加形参代表可变元组参数,一般用*args。
(2)、可变元组可接收任意个参数,以元组的形式储存。
(3)、调用函数时,我们可以传递任意数量的位置参数给 *args,它们将被打包成一个元组传递给函数。
def f1(a, b, c, *args):
    print(a, b, c, args, *args, type(args))
    return args


f1(10, 20, 30, 40, 50)
print(f1)
# 10 20 30 (40, 50) 40 50 <class 'tuple'>
# <function f1 at 0x0000022DBFA79C60>
(4)、在函数内部可以通过遍历args元组来访问传递的参数值。
def my_f(*args):
    for arg in args:
        print(arg)


my_f('a', 'b', 'c', 'd', 'e')
# a
# b
# c
# d
# e

5、可变字典参数

(1)、**kwargs 允许函数接受任意数量的关键字参数,并将它们作为一个字典传递给函数。
def my_fun(a, b, f=5, **kwargs):
    print(a, b, f, kwargs, type(kwargs))


my_fun(a='你好', b=2, c=None, d=4, e=5)
# 你好 2 5 {'c': None, 'd': 4, 'e': 5} <class 'dict'>
(2)、在函数内部,可以通过访问 kwargs 字典的键值对来获取传递的参数值。
def my_function(**kwargs):
    for key, value in kwargs.items():
        print(key, value)

my_function(fruit='apple', color='red', price=1.99)
# fruit apple
# color red
# price 1.99

6、*args和**kwargs可以与其他参数一起使用,但是通常约定将它们放在最后。

def my_fun(a, *args, **kwargs):
    print(a, args, kwargs)


my_fun(3, 4, 5, 6, 7, b=10, c=bool, e=3.14)
# 3 (4, 5, 6, 7) {'b': 10, 'c': <class 'bool'>, 'e': 3.14}

六、匿名函数

lambda 匿名函数(没有函数名)

1、格式

(1)、lambda 形参:返回值
即:lambda 参数列表,多个参数使用逗号隔开 : 返回值只支持简单表达式
  • 形参可以是多个,返回值只能有一个
  • 形参可以省略,但是必须有返回值
  • 调用时,和普通函数操作一样
f4 = lambda: print('可以只有返回值,不传参数')
f4()

f5 = lambda a, b: a if a > b else b

print(f5(10, 20), type(f5(10, 20)))

print(f5('a', 'g'), type(f5('a', 'g')))
# 20 <class 'int'>
# g <class 'str'>

2、应用场景:通常作为实参赋给形参

  • 将匿名函数赋予函数中,在函数中调用匿名函数使用;相当于在函数中调用另一个比较简单的函数。
def f1(n, f):
     for i in range(n):
          f()


f1(5, lambda: print('匿名函数'))
# 匿名函数
# 匿名函数
# 匿名函数
# 匿名函数
# 匿名函数

3、实战

(1)、使用sort() 方法,根据列表中元素的长度,对列表进行排序。

思路:

  • 使用 lambda 函数作为 sort() 方法的关键字参数来对列表进行排序。
  • 使用 len() 函数作为排序的依据,表示按照字符串长度递增的顺序排序。
  • 最后,使用 print() 函数打印输出排序后的列表。
# 使用 lambda 函数对列表中的元素进行排序
fruits = ["apple", "banana", "cherry", "date"]
# 将fruits中的每个元素赋予x,返回x的长度;根据长度排序
fruits.sort(key=lambda x: len(x))
print(fruits)
# ['date', 'apple', 'banana', 'cherry']

注意:sort中的key参数

  • 在 Python 中,list 对象的 sort() 方法用于对列表中的元素进行排序。其中,key 是一个可选参数,用于指定排序的依据。
  • 如果省略了 key 参数,则默认按照元素的大小进行排序,即按照元素的自然顺序进行排序(例如,数字从小到大,字符串按照字典序排序)。
  • 如果指定了 key 参数,则应该传递一个函数作为参数,该函数将被用于计算每个元素的排序键值。sort() 方法将根据排序键值对元素进行排序,并返回排序后的列表。
  • 即key重新定义排序方式
(2)、使用maxt() 方法,根据列表中字典的信息,找出以名字排序最大的字典,以及年龄最大的字典信息。
l = [{"name": "a", "age": 100},
     {"name": "b", "age": 80},
     {"name": "c", "age": 60},
     {"name": "d", "age": 30}
     ]
# # 打印名称最大字典
print(max(l, key=lambda e: e['name']))
# # 打印最大年龄字典
print(max(l, key=lambda e: e['age']))
# {'name': 'd', 'age': 30}
# {'name': 'a', 'age': 100}

使用匿名函数相当于再次定义一个普通函数

def f1(e):
    """
    一个一个遍历列表
    :param e: 列表中的每一项
    :return: 返回每一项的age
    """
    return e['age']

print(max(l, key=f1))
# {'name': 'a', 'age': 100}

七、递归函数

  •  要求有出口
  •  自己调用自己

1、getrecursionlimit():获取递归深度;setrecursionlimit()修改递归最大深度

import sys
# 获取递归深度
print(sys.getrecursionlimit())
# 1000

# 修改递归最大深度
sys.setrecursionlimit(2000)
print(sys.getrecursionlimit())

2、实战

(1)、求前100项的累加和。
def f(n):
    """
    累加和
    :param n: 加到几
    :return: 返回自己
    """
    # 递归出口
    if n == 1:
        return 1
    else:
        # 本函数调用本函数
        return n + f(n - 1)

print(f(100))
(2)、求前5项的阶乘
def f(n):
    """
    阶乘和
    :param n: 乘到n
    :return: 返回自己直到1
    """
    if n == 1:
        # 递归出口
        return 1
    else:
        # 递归调用自己
        return n * f(n - 1)
print(f(5))
(3)、求斐波那契数列的第7个数
def f(n):
    if n == 1 or n == 2:
        return 1
    else:
        return f(n-1) + f(n-2)

print(f(7))

八、函数的实战

1、封装函数求1+2+3+...+100的和

def total(num):
    """
    求1+2+3+...+n的和
    :param num: 输入的数值
    :return: 数值的总和
    """
    total_num = 0
    for i in range(1, num + 1):
        total_num += i
    return total_num


n = int(input("请输入一个数:"))
print(f'和为:{total(n)}')

2、封装函数包含两个形参start与end 返回start到end之间奇数的和

def odd_num(start, end):
    """
    返回start到end之间奇数的和
    :param start: 起始数
    :param end: 结束值
    :return: 奇数和
    """
    total = 0
    for i in range(start, end + 1):
        if i % 2:
            total += i
    return total


start_num = int(input('请输入开始值:'))
end_num = int(input('请输入结束值:'))
print(f'奇数和为:{odd_num(start_num, end_num)}')

3、封装函数:可以判断一个数是否是质数

def is_prime(n):
    """
    判断一个数是否是质数
    :param n: 输入数
    :return: 判断结果
    """
    for i in range(2, n):
        if n % i == 0:
            return '不是质数'
    else:
        return '是质数'


num = int(input('请输入一个数字:'))
print(is_prime(num))
方法二:
def is_prime(n):
    for i in range(2, n):
        if n % i == 0:
            return False
    # return True

num = int(input('请输入一个数:'))
r = is_prime(num)
if r == False:
    print('不是质数')
else:
    print('是质数')

4、封装函数:求1000以内的质数对

def is_prime(n):
    for i in range(2, n):
        if n % i == 0:
            return False
    else:
        return True


def is_prime_pairs(num, step):
    result = []
    for i in range(2, num-step+1):
        if is_prime(i) and is_prime(i + step):
            result.append((i, i + step))
    return result


end_num = int(input('请输入结束边界:'))
step_num = int(input('请输入两数之间的步长:'))
print(is_prime_pairs(end_num, step_num))
print(len(is_prime_pairs(end_num, step_num)))

5、编写函数求start到end以内所有的相差为step的素数对

def is_prime(n):
    for i in range(2, n):
        if n % i == 0:
            return False
    else:
        return True


def is_prime_pairs(start, end, step):
    for i in range(start, end-step+1):
        if is_prime(i) and is_prime(i + step):
            print(i, i + step)


start_num = int(input('请输入开始边界:'))
end_num = int(input('请输入结束边界:'))
step_num = int(input('请输入两数之间的步长:'))
is_prime_pairs(start_num, end_num, step_num)

6、斐波那契数列指的是这样一个数列:1,1,2,3,5,8,13,21,34,55,89...

(1)、编写函数返回斐波那契数列的第n个数。
def fib_num(n):
    """
    返回斐波那契数列的第n个数
    :param n:斐波那契数列的第n个数
    :return:返回的数值
    """
    first = 1
    second = 1
    current = None
    for i in range(2, n):
        current = first + second
        first = second
        second = current
    return current


num = int(input('请输入一个数:'))
if num in [1, 2]:
    print(f'第{num}个数为:1')
else:
    print(f'第{num}个数为:{fib_num(num)}')
(2)、返回斐波那契数列的前n个数
def fib_num(n):
    """
    返回斐波那契数列的前n个数
    :param n:斐波那契数列的第n个数
    :return:返回的数值
    """
    first = 1
    second = 1
    if n == 1:
        return [first]
    elif n == 2:
        return [first, second]
    else:
        result = [first, second]
        for i in range(2, n):
            current = first + second
            result.append(current)
            first = second
            second = current
        return result


num = int(input('请输入一个数:'))
print(fib_num(num))

7、编写一个函数,接受一个数字n作为参数,该函数可以随机生成n个整数,并返回 所有整数的最大值

def max_num(n):
    """
    随机生成n个整数,返回整数列表,及所有整数的最大值
    :param n:
    :return:
    """
    max_value = -math.inf # 也可以定义为None,if是空,将第一数值给它,不是进行比较
    l = []
    for i in range(n):
        num = random.randint(-1000, 1000)
        l.append(num)
        if num > max_value:
            max_value = num
    print(l)
    return max_value


n_num = int(input('请输入一个整数:'))
print(max_num(n_num))

8、编写一个 Python 函数,接受一个字符串作为参数,并返回该字符串中所有大写字母的数量。

def up_num(str_value):
    """
    返回字符串中所有大写字母的数量
    :param str_value: 输入的字符串
    :return: 字符串中所有大写字母的数量
    """
    count = 0
    for e in str_value:
        # 方法一:
        # if 'A' <= e <= 'Z':
        # 方法二:
        if e.isupper():
            count += 1
    return count


my_str = input('请输入一个字符串:')
print(up_num(my_str))

9、编写函数,接受一个字符串和一个字符作为参数,并返回该字符串中该字符出现的次数。

方法一:
def find_num(str_value, char_value):
    return str_value.count(char_value)
方法二:
def find_num(str_value, char_value):
    """
    返回字符串中该字符出现的次数
    :param str_value: 输入的字符串
    :param char_value: 查找的字符
    :return: 字符出现的次数
    """
    count = 0
    for e in str_value:
        if e == char_value:
            count += 1
    return count


my_str = input('请输入一个字符串:').lower()
my_char = input('请输入一个字符:').lower()
print(find_num(my_str, my_char))

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值