Python | 第七章 | 函数

P60 多重循环控制(1) 2024/8/30

一、基本介绍

  1. 将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for ,while均可以作为外层循环和内层循环。【建议一般使用两层,最多不要超过3层,否则,代码的可读性不好】

image-20240830102651457

  1. 实质上,嵌套循环就是把内层循环当成外层循环的循环体。
  2. 如果外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n
# @Author :zjc
# @File   :019_multiple_for_while.py
# Time    :2024/8/30 10:29

for i in range(2):
    for j in range(3):
        print("i=", i, "j=", j)

二、经典案例

  1. 使用for循环完成下面的案例
    请编写一个程序,可以接收一个整数,表示层数(total_level),打印出空心金字塔

image-20240830103627407

1、金字塔思路实现

image-20240830104221027

image-20240830104245703

2、代码实现

# @Author :zjc
# @File   :020_blank_pyrimid.py
# Time    :2024/8/30 10:38

"""
 思路分析:
    - 先死后活
     1、先不考虑层数变化,假定就是5层,后面做活
    - 化繁为简
     1、打印矩形
     2、打印直角三角形
     3、打印金字塔
     4、打印空心金字塔
"""

"""
         1.打印矩形
    *****
    *****
    *****
    *****
    *****
         2.打印直角三角形
    *           1层:1个*
    **          2层:2个*
    ***         3层:3个*
    ****        4层:4个*
    *****       5层:5个*
         3、打印金字塔
  4个空格       *       1层:1个*
  3个空格      ***      2层:3个*
  2个空格     *****     3层:5个*
  1个空格    *******    4层:7个*
  0个空格   *********   5层:9个*
  5-i个空格             i层:2*i-1
         4、打印空心金字塔
                *       分析:每层的两边输出*和最后一层输出*
               * *          1.通过if判断输出*,else 输出空格
              *   *         2.还要输出空格,否则两个*号在一起
             *     *
            **********
"""
# 总层数
# 1. 对于需要替换的地方进行替换,循环中需要加1
total_level = 10

# i控制我们的层数
for i in range(1, total_level+1):
    # 1.在用k表示输出空格数
    for k in range(total_level - i):
        print(" ", end="")
    # 1. j控制每层输出*号的个数
    # 2. 改成i+1,因为(1,2)中只有1
    # for j in range(1, i+1):
    # 3. 也可以直接改成i默认开始为0,(0,6)
    # 4.再次改进,2*i-1
    for j in range(2 * i - 1):
        # j == 2 * (i - 1)
        if j == 0 or j == 2 * (i - 1) or i == total_level :
            # 这里end="",表示输出不换行
            print("*", end="")
        else:
            print(" ", end="")
    # 每层输出后进行换行,自动换行
    print("")

三、课后练习

image-20240830112738334

在Python的for循环中,-1通常不是for循环本身的一部分,而是与循环的迭代方式有关,特别是在使用range()函数进行迭代时。range()函数用于生成一个数字序列,它接受一到三个参数:起始值(默认为0),结束值(不包括此值),以及步长(默认为1)。

当你在range()函数中使用-1作为步长时,它意味着序列将按递减的顺序生成数字。这在处理需要逆向迭代的情况时非常有用,比如打印一个倒序的数字列表,或者在你的例子中,打印菱形的下半部分。

例如:

for i in range(5, 0, -1):  
 print(i)

这段代码将输出:

5  
4  
3  
2  
1
# @Author :zjc
# @File   :020_blank_pyrimid.py
# Time    :2024/8/30 10:38

# 总层数
# 1. 对于需要替换的地方进行替换,循环中需要加1
total_level = 5

# i控制我们的层数
for i in range(1, total_level + 1):
    # 1.在用k表示输出空格数
    for k in range(total_level - i):
        print(" ", end="")
    # 1. j控制每层输出*号的个数
    # 2. 改成i+1,因为(1,2)中只有1
    # for j in range(1, i+1):
    # 3. 也可以直接改成i默认开始为0,(0,6)
    # 4.再次改进,2*i-1
    for j in range(2 * i - 1):
        # j == 2 * (i - 1)
        if j == 0 or j == 2 * (i - 1):
            # 这里end="",表示输出不换行
            print("*", end="")
        else:
            print(" ", end="")
    # 每层输出后进行换行,自动换行
    print("")

# 打印下半部分(更简单的逻辑)
# 1. -1表示逆序打印,5,4,3,2,1
# 2.  只会之行4次:4,3,2,1
for i in range(total_level - 1, 0, -1):

    # 打印前导空格
    # 1. 5-4=1 5-3=2 5-2=3 5-1=4
    for k in range(total_level - i):
        print(" ", end="")

        # 打印星号
    for j in range(2 * i - 1):
        # 第一次:2*4-1=7,j=0就是最开始,2*4-2=6,因为j从0开始,要减2
        if j == 0 or j == 2 * i - 2:
            print("*", end="")
        else:
            print(" ", end="")
    print("")  # 换行

image-20240830143931290

P61 多重循环(2)2024/8/30

一、应用实例演示

image-20240830162155265

# @Author :zjc
# @File   :022_stu_score.py
# Time    :2024/8/30 16:22

# 1、统计3个班成绩情况,每个班有5名同学,要求完成[文件: stu_score.py]
# 1)求出各个班的平均分和所有班级的平均分,学生的成绩从键盘输入
# 2)统计三个班及格人数
# 重要的编程思路:(1)化繁为简(2)先死后活[先考虑3个班,每个班5名学生]

# 化繁为简
# 1.统计1个班成绩情况,求出一个班的平均分
# 2.统计3个班成绩情况,求出各个班的平均分、所有班级的平均分和及格人数

# 3.将班级和学生做成一个变量
# 定义班级,学生个数
class_num = 3
stu_sum = 5
# 统计所有班级的平均分
total = 0.0

# 统计所有的及格人数
pass_num = 0

for j in range(1, class_num+1):
    # 定义相关变量:统计一个班的总分
    # 1. 定义在第一个循环开始,因为每一次要清零
    sum = 0.0
    # 统计一个班成绩情况,求出每个班平均分-for 循环5次,接收学员的成绩
    for i in range(1, stu_sum+1):

        score = float(input(f"请输入第{j}个班的第{i}个学生的成绩:"))
        # 判断是否及格
        if score >= 60.0:
            pass_num += 1
        # 累加到sum
        sum += score
    print(f"第{j}班的情况,平均分{sum / stu_sum}")

    # 将sum累加到total,总平均分
    total += sum

print(f"所有班级的平均分{total / (stu_sum * class_num)} 及格人数:{pass_num}")

image-20240830164747127

image-20240830164800227

# @Author :zjc
# @File   :023_99_multiply_table.py
# Time    :2024/8/30 16:48

# 1.定义变量i和j

for i in range(1, 10):
    for j in range(1, i + 1):
        print(f" {j}*{i}={i * j}", end="")
    print("")

image-20240830171147707

P62 break语句(1)2024/8/30

一、需求

  • 需求
    • 随机生成1-100的一个数,直到生成了97这个数,看看你一共用了几次?
    • 提示使用random模块的randint()函数来生成随机数,该函数的语法为

image-20240830172603752

image-20240830172941932

代码演示

# 演示random.randint()的使用
# 导入random模块

import random

for i in range(8):
    n = random.randint(1, 100)
    print(n)

二、基本介绍

  • 说明
    break语句拥用于终止某个语句块的执行,使用在循环中

  • break 流程示意图

image-20240830173214322

  • 代码演示
# @Author :zjc
# @File   :024_num_break.py
# Time    :2024/8/30 17:33

# 随机生成1-100的一个数,直到生成了97这个数,看看你一共用了几次?
"""
    思路分析:
    1. 定义变量count 统计一共用了多少次 count += 1
    2. 使用while true 无限循环生成随机数,直到生成97就退出
    3. 输出count 即可
"""
# 导入模块
import random

count = 0

while True:
    # 生成随机数:
    n = random.randint(1, 100)
    # 统计次数:
    count += 1
    if n == 97:
        break
print(f"生成97一共用了{count}次")

P63 break语句(2)2024/8/30

一、注意事项和细节

  1. break语句是用在for或while循环所嵌套的代码
  2. 它会终结最近的外层循环,如果循环有可选的else子句,也会跳过该子句
# @Author :zjc
# @File   :025_break_01.py
# Time    :2024/8/30 17:48

count = 0
while True:
    print("hi while")
    count += 1
    if count == 3:
        # 会终结外层循环,不会执行下面的else
        break
    while True:
        print("OK while")
        # 只会终结内存循环
        break
else:
    print("Hello, while")
  1. 如果一个for循环被break所终结,该循环的控制变量会保持其当前值
nums = [1, 2, 3, 4, 5, 6]
for i in nums:
    if i > 3:
        break
print("i=", i) # i = 4

二、课堂练习题

  1. 1-100以内的数求和,求出当和第一次大于20的当前控制循环的变量值是多少?
# @Author :zjc
# @File   :026_break_exercise01.py
# Time    :2024/8/30 19:47

# 1-100以内的数求和,求出当和第一次大于20的当前控制循环的变量值是多少?
"""
    思路分析:
    1. 定义变量sum记录总和
    2. for循环遍历1-100,当sum > 20时,就退出 break
    3. 输出

"""
sum = 0
for i in range(1, 101):
    # 累加
    sum += i
    # 判断
    if sum > 20:
        print("当和大于20时,i为{}".format(i))
        break
print("总和为", sum)

2、实现登录验证,有三次机会,如果用户名为"张无忌",密码"888”提示登录成功,否则提示还有几次机会,请使用for+break完成

# @Author :zjc
# @File   :027_break_exercise02.py
# Time    :2024/8/30 19:55

# 2、实现登录验证,有三次机会,如果用户名为"张无忌",密码"888”提示登录成功,否则提示还有几次机会,请使用for+break完成

"""
    思路分析:
    1、定义变量:密码,
    2、使用for循环判断三次,如果成功则break
"""

for i in range(3, 0, -1):
    username = input("请输入用户名:")
    password = int(input("请输入密码:"))
    # 判断是否登录成功
    if username == "张无忌" and password == 888:
        print("登录成功")
        break
    print("你还有{}次机会".format(i-1))

image-20240830201319568

P64 continue语句 2024/8/31

一、基本介绍

  1. continue语句用于for或while循环所嵌套的代码中
  2. continue语句用于结束本次循环,继续执行循环的下一个轮次
  3. 老韩说明:继续执行的是:该continue最近的外层循环的下一个轮次
  • 以while循环为例流程图

image-20240831102741064

  • 代码分析

image-20240831102832090

  • 内存分析图

image-20240831103054653

二、课堂练习题

image-20240831103121557

image-20240831103559506

P65 return 语句 2024/8/31

一、基本介绍

  1. return使用在函数,表示跳出所在的函数
  2. 在讲解函数的时候,会详细的介绍,这里我们简单的演示一下
# @Author :zjc
# @File   :028_return.py
# Time    :2024/8/31 10:57


# f1是一个函数
def f1():
    for i in range(1, 5):
        if i == 3:
            # return就是跳出函数
            return
            # break
            # continue
            print("i =", i)
    print("结束了for..")
    
# 调用函数
f1()

P66 本章作业和小结 2024/8/31

一、题目练习

1、编程题
某人有100,000元,每经过一次路口,需要交费,规则如下:

当现金>50000时,每次交5%
当现金<=50000时,每次交1000
编程计算该人可以经过多少次路口,使用while + break方式完成

# @Author :zjc
# @File   :029_homework01.py
# Time    :2024/8/31 11:14

"""
   思路分析:
   1、定义变量 钱10000元,经过路口次数count
   2、while循环+if判断执行相应操作
   3、当钱不足1000时跳出循环
   4、输出count即可
"""

money = 100000
count = 0
while True:
   if money < 1000:
       break
   if money > 50000:
       money -= money * 0.05
       count += 1
   else:
       money -= 1000
       count += 1
print("共经过{}次路口剩余的钱为{}".format(count, money))
  • 知识点回顾

image-20240831114533756

image-20240831114659549

P67 函数 2024/8/31

一、需求分析

  • 请大家完成这样一个需求
    输入两个数,再输入一个运算符(+,-,*,/),得到结果
  • 先使用传统的方式来解决,看看有什么问题没有?
n1 = float(input("请输入一个数"))
n2 = float(input("请输入一个数"))
oper = input("请输入运算符+,-,*,/:")
res = 0.0
if oper == "+":
    res = n1 + n2
elif oper == "-":
    res = n1 - n2
elif oper == "*":
    res = n1 * n2
elif oper == "/":
    res = n1 / n2
else:
    print("输出的运算符不对.")

print(n1, oper, n2, "=", res)

问题来了

  1. 如果我们下面还要进行一次这样的操作科

  2. 或者,在其他文件,也有这样的需求,咋办?

分析传统解决方式,有什么缺点

-分析出问题

1)代码冗余
2)不利于代码的维护

二、基本介绍

  1. 为完成某一功能的程序指令(语句)的集合,称为函数

  2. 在python中,函数分为:系统函数自定义函数(查看python文档https://docs.python.org/zh-cn/3.11/library/functions.html.)

    • 模块提供的函数:https://docs.python.org/zh-cn/3.11/py-modindex.html#cap-m
  3. 定义函数

    • 定义函数使用关键字def,后跟函数名与括号内的形参列表。函数语句从下一行开始,并且必须缩进.

总结

1、内置函数和模块中提供的函数都是系统函数(由python提供)

2、自定义函数是程序员根据业务需要开发的

函数的好处

1、提高代码的复用性
2、可以将实现的细节封装起来,然后供其他用户来调用即可

三、基本语法

image-20240831192628898

  1. 函数代码块以def 关键词开头,后接函数标识符名称和圆括号()。

  2. 函数内容以冒号:起始,并且缩进。

  3. 函数参数(a,b),可以有多个,也可以没有即直接是(),(a,b)也称为形参列表。

  4. 函数可以有返回值,也可以没有,如果没有return相当于返回 None。

  • 函数的调用
  1. 函数定义好了,并不会自动执行,需要程序员调用,才会执行

  2. 调用方式:函数名(实参列表),比如max(10,20)

  • 快速入门案例
    1. 题目1:自定义cry函数,输出"小猫,瞄瞄叫…"
# @Author :zjc
# @File   :02_function_exercise01.py
# Time    :2024/8/31 19:31

# 1、自定义cry函数,输出"小猫,瞄瞄叫..."
"""
    思路分析:
    1、函数名 cry
    2、形参列表:无
    3、函数体:完成 输出”小猫,喵喵叫“
"""

# 定义函数
def cry():
    print("小猫,喵喵叫")

# 调用函数
cry()
  1. 题目2:自定义cal01函数,可以计算从1+…+1000的结果
# 题目2:自定义cal01函数,可以计算从1+..+1000的结果
"""
    思路分析:
    1、函数名 cal01
    2、形参列表
    3、函数体:计算从1+..+1000的结果
"""
# 定义函数
def cal01():
    sum = 0
    for i in range(1, 1001):
        sum += i
    print(f"1+...1000的结果:{sum}")

# 调用函数
cal01()
  1. 自定义cal02函数,该函数可以接收一个数n,计算从1+…+n的结果Ⅰ
# 自定义cal02函数,该函数可以接收一个数n,计算从1+..+n的结果

"""
    思路分析:
    1、函数名:cal02
    2、形参列表:(n)
    3、函数体:计算从1+..+n的结果
"""

def cal02(n):
    total = 0
    for i in range(1, n + 1):
        total += i
    print("total = ", total)

# 调用
# 1.调用函数时传入了实参
# 2.相当于把100赋给了形参n
cal02(100)
  1. 自定义get_sum函数,可以计算两个数的和,并返回结果.
# 自定义get_sum函数,可以计算两个数的和,并返回结果.
"""
    思路分析:
    1. 函数名 get_sum
    2. 形参列表(num1,num2)
    3. 函数体:可以计算两个数的和,并返回结果.
"""

# 定义函数
def get_sum(num1, num2):
    total = num1 + num2
    return total

# 调用
# 1. 表示传入了两个实参10,50,分别赋值给形参
# 2. result 接收get_sum函数返回的结果
result = get_sum(10, 50)
print("result = ", result)
  1. 用函数解决先前的计算问题
def cal():
    n1 = float(input("请输入一个数"))
    n2 = float(input("请输入一个数"))
    oper = input("请输入运算符+,-,*,/:")
    res = 0.0
    if oper == "+":
        res = n1 + n2
    elif oper == "-":
        res = n1 - n2
    elif oper == "*":
        res = n1 * n2
    elif oper == "/":
        res = n1 / n2
    else:
        print("输出的运算符不对.")

    print(n1, oper, n2, "=", res)

# 调用函数
cal()

# 如果还有这样的需求,调用函数cal就行
cal()

P68 函数调用机制 2024/9/1

一、函数通常理解

image-20240901112941200

image-20240901113043219

二、调用过程

  • 函数-调用过程(!!!)

      1. 为了让大家更好的理解函数调用过程,给大家画一个示意图,这个很重要的
      1. 老韩就以get sum函数的调用为例讲行分析
  • 调用过程分析图

image-20240901113739364

三、return语句

image-20240901113857317

内置常量:https://docs.python.org/zh-cn/3.11/library/constants.html

image-20240901114033765

代码演示

def f1():
    print("hi")

# i 就是none
i = f1()
print("i = ", i)

P69 函数注意事项 2024/9/1

一、注意事项和使用细节

  1. 函数的参数列表可以是多个,也可以没有。
  2. 函数的命名遵循标识符命名规则和规范,具体参考前面讲过的标识符命名规则和规范。

image-20240901121125684

  1. 函数中的变量是局部的,函数外不生效。
# 函数中的变量是局部的,函数外不生效
def hi():
    n = 10

hi()
# 函数内部定义的n,在函数外部不能使用print("n:", n)
print("n:", n)
  1. 如果同一个文件,出现两个函数名相同的函数,则以就近原则进行调用。
# 如果同一个文件,出现两个函数名相同的函数,则以就近原则进行调用.
def cry():
    print("cry()..hi...")


def cry():
    print("cry()..ok...")

# 这个cry会默认就近原则,即第二个cry()
cry()
  1. 调用函数时,根据函数定义的参数位置来传递参数,这种传参方式就是位置参数,传递的实参和定义的的形参顺序和个数必须一致,同时定义的形参,不用指定数据类型,会根据传入的实参决定。
def car_info(name, price, color):
    print(f"name->{name} price->{price} color->{color}")

# 传递的实参和定义的的形参顺序和个数必须一致,否则报 TypeError 错误
car_info("宝马", 500000, "red", 11)
  1. 函数可以有多个返回值,返回数据类型不受限制
# 比如函数接收两个数,返回这两个数的和、差
def f2(n1, n2):
    return n1 + n2, n1 - n2

r1, r2 = f2(10, 20)
print(f"r1->{r1} r2->{r2}")
  1. 函数支持关键字参数:
    -函数调用时,可以通过“形参名=实参值”形式传递参数

    -这样可以不受参数传递顺序的限制

def book_info(name, price, author, amount):
    print(f"name->{name} price->{price} author->{author} amount->{amount}")

# 通常调用方式,一一对应
book_info("红楼梦", 60, "曹雪芹", 30000)
# book_info("红楼梦",60,30000,"曹雪芹")

# 关键字参数
print(" ------------关键字参数------------")
book_info(name="红楼梦", price=60, amount=30000, author="曹雪芹")
# 1.也可以前两个按照顺序匹配,后面的关键字匹配
book_info("红楼梦", 60, amount=6000, author="曹雪芹")
  1. 函数支持默认参数/缺省参数
    -定义函数时,可以给参数提供默认值,调用函数时,指定了实参,则以指定为准,没有指定,则以默认值为准

    -默认参数,需要放在参数列表后

# 8、函数支持默认参数/缺省参数
# --定义函数时,可以给参数提供默认值,调用函数时,指定了实参,则以指定为准,没有指定,则以默认值为准
def book_info2(name='<<thinking in python>>', price=66.8, author='龟叔', amount=1000):
    print(f" name->{name} price->{price} author->{author} amount->{amount}")


# 调用测试
book_info2()
# 1.指定了实参,则以指定为准,没有指定,则以默认值为准
book_info2('<c<study python>> ')


# -默认参数,需要放在参数列表草I
def book_info3(name, price, author='龟叔', amount=1000):
    # 1、如果将默认值放在前面是不行的,错误写法:
    # def book_info3(author='龟叔', amount=1000,name, price ):
    print(f"name->{name} price->{price} author->{author} amount->{amount}")

# 调用测试
book_info3("<<pythdn揭秘>>", 999)
  1. 函数支持可变参数/不定长参数
    -应用场景: 当调用函数时,不确定传入多少个实参的情况

    -传入的多个实参,会被组成一个元组(tuple),后面会详细讲解元组,小伙伴们这里先简单的了解下

    –简单说明: 元组可以储存多个数据项

# 比如我们要计算多个数的和,但是不确定是几个数*[0到多]

def sum(*args): # args -> (1, 2)
    # 输出了args的数据和类型(1,2,)
    print(f"args->{args}类型是->{type(args)}")
    total = 0
    # 对args进行遍历,即对元组遍历
    for ele in args:
        total += ele
    return total


# 调用测试
result = sum(1, 2)
print(f"result->{result}")
  1. 函数的可变参数/不定长参数还支持多个关键字参数,也就是多个"形参名=实参值"

    -应用场景: 当调用函数时,不确定传入多少个关键字参数的情况

    -传入的多个关键字参数,会被组成一个字典(dict),后面会详细讲解字典,这里简单的了解下

    –简单说明: 字典可以储存多个键=值的数据项

# 如果我们希望传入的参数多个(不确定),并且使用关键字参数方式传入,怎么办?
# def person_info(name="hsp", age=18, email="hsp@qq.com",color = "y"...)

# 比如我们需要接收一个人的信息,但是有哪些信息是不确定的,就可以使用关键字可变参数

def person_info(**args):
    # 输出args的数据: {name="hsp", age=18, email="hsp@qq.com"}
    print(f"args->{args}类型->{type(args)}")
    # 遍历args,是一个字典,下面的arg_name就是取出各个参数名
    # args[arg_name]就是取出参数值,相当于在遍历字典
    for arg_name in args: # {'name': 'hsp', 'age': 18, 'email': 'hsp@qq.com'}
        print(f"参数名->{arg_name}参数值->{args[arg_name]}")


# 测试
person_info(name="hsp", age=18, email="hsp@qq.com", sex = "男", address = "北京")
# 不传就是没数据
person_info()
  1. python调用另一个.py文件中的函数

image-20240901161647953

# @Author :zjc
# @File   :f2.py
# Time    :2024/9/1 16:17

# 在f2.py使用f1.py的函数

# 导入f1.py(模块),就可以使用
import f1

f1.add(10, 30)
f1.add(10, 40)
f1.add(10, 50)
# @Author :zjc
# @File   :f1.py
# Time    :2024/9/1 16:17

def add(x, y):
    print("x + y= {}".format(x + y))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一颗星星辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值