Play Open
Loading Please wait Loading Please wait Loading Please wait Loading Please wait Loading Please wait Loading Please wait

函数的概念及其重要性

函数的概念及其重要性

在前几章中,我们已经介绍了数据的表达和数据处理的控制流程,从而可以编写简单的程序实现特定功能。然而,我们在代码复用性、程序结构框架和代码维护性等方面遇到了一些不便。因此,迫切需要引入一种新的方法来解决这些问题——这就是我们今天要讨论的主题:函数。

为什么使用函数?

函数具有三大重要作用:

提高代码复用性:将常用代码封装成函数,减少重复。分解复杂问题:将复杂问题分解为多个简单问题,便于管理和解决。提升代码维护性:只需修改函数内部逻辑,不影响其他部分。

函数的基本结构

函数可以理解为一个“白箱子”,具有输入、处理和输出三个部分。其三要素分别为:

参数(输入)函数体(处理过程)返回值(输出)

函数的定义与调用

定义函数

函数定义的基本语法如下:

def 函数名(参数):

函数体

return 返回值

例如,定义一个计算阶乘的函数:

def factorial(n):

result = 1

for i in range(1, n + 1):

result *= i

return result

调用函数

调用函数时,使用函数名并传递参数:

factorial(5)

参数传递

形参与实参

形参:函数定义时的参数。实参:函数调用时传递的实际值。

位置参数

位置参数按照位置顺序传递:

def function(x, y, z):

print(x, y, z)

function(1, 2, 3)

关键字参数

关键字参数通过参数名传递,打破位置限制:

function(y=1, z=2, x=3)

混合使用

位置参数必须在关键字参数之前:

function(1, y=2, z=3)

默认参数

为某些参数设置默认值:

def register(name, age, sex=‘male’):

print(name, age, sex)

可变参数

单星号 *args 接收多个位置参数:

def function(x, y, *args):

print(x, y, args)

function(1, 2, 3, 4, 5)

双星号 **kwargs 接收多个关键字参数:

def function(x, y, **kwargs):

print(x, y, kwargs)

function(1, 2, a=3, b=4)

函数体与变量作用域

局部变量

仅在函数体内定义的变量:

def function():

z = x * y

return z

全局变量

在外部程序中定义的变量:

n = 10

def function():

global z

z = x * y * n

返回值

返回单个或多个值:

def function():

return value

def function():

return value1, value2

模块化编程实例

羽毛球比赛胜负模拟

主要逻辑

获取原始数据:get_input()模拟多场比赛:sim_n_games()汇总输出结果:print_summary()

详细步骤

获取原始数据

def get_input():

prob_a = float(input("Enter probability for A: "))

prob_b = 1 - prob_a

num_games = int(input("Enter number of games to simulate: "))

return prob_a, prob_b, num_games

模拟单场比赛

def sim_one_game(prob_a, prob_b):

score_a = score_b = 0

while not game_over(score_a, score_b):

if random.random() < prob_a:

score_a += 1

else:

score_b += 1

return score_a, score_b

模拟多场比赛

def sim_n_games(prob_a, prob_b, num_games):

wins_a = wins_b = 0

for _ in range(num_games):

score_a, score_b = sim_one_game(prob_a, prob_b)

if score_a > score_b:

wins_a += 1

else:

wins_b += 1

return wins_a, wins_b

汇总输出结果

def print_summary(wins_a, wins_b, num_games):

print(f"Summary of {num_games} games:“)

print(f"A won {wins_a / num_games * 100:.2f}%”)

print(f"B won {wins_b / num_games * 100:.2f}%")

匿名函数

匿名函数使用 lambda 定义,常用于排序和最大/最小值计算:

sorted_list = sorted(data, key=lambda x: x[1])

max_value = max(data, key=lambda x: x[1])

面向过程与面向对象编程

面向过程编程

以事件过程为主线,关注事情的发生过程。

面向对象编程

以对象为核心,关注对象的属性和行为。

函数定义与调用

单选题

为什么我们要使用函数?

A. 提高代码复用性

B. 将复杂的逻辑关系分解成简单逻辑关系的组合

C. 提高代码维护和管理的效率

D. 以上都是

答案: D

函数的三要素不包括以下哪一项?

A. 参数

B. 函数体

C. 返回值

D. 注释

答案: D

在函数定义时,圆括号里的参数称为?

A. 实参

B. 形参

C. 默认参数

D. 可变参数

答案: B

当函数调用时传递给函数的参数称为?

A. 形参

B. 实参

C. 默认参数

D. 关键字参数

答案: B

哪种参数传递方式适用于参数较少的情况?

A. 位置参数

B. 关键字参数

C. 混合参数

D. 默认参数

答案: A

哪种参数传递方式可以打破位置的限制?

A. 位置参数

B. 关键字参数

C. 混合参数

D. 默认参数

答案: B

关于默认参数,下列说法正确的是?

A. 默认参数必须放在非默认参数前面

B. 默认参数必须放在非默认参数后面

C. 默认参数可以放在任意位置

D. 默认参数不能是不可变类型

答案: B

关于可变参数,下列说法正确的是?

A. 使用*args可以接收任意多个位置参数

B. 使用**kwargs可以接收任意多个关键字参数

C. *args接收的参数会被打包成元组

D. 以上都是

答案: D

判断题

函数体内的变量一定是局部变量。

答案: 正确

全局变量可以在函数体内直接访问。

答案: 正确

局部变量可以在函数体外部访问。

答案: 错误

函数的返回值只能是一个值。

答案: 错误

没有return语句的函数返回值是None。

答案: 正确

填空题

函数的定义关键字是______。

答案: def

函数的返回值使用______关键字实现。

答案: return

将复杂的逻辑关系分解成简单逻辑关系的组合的思想称为______。

答案: 分而治之

函数体内的变量称为______变量。

答案: 局部

函数体外部定义的变量称为______变量。

答案: 全局

编程题

编写一个函数calculate_factorial,接受一个整数n作为参数,返回n的阶乘。

def calculate_factorial(n):

if n == 0 or n == 1:

return 1

result = 1

for i in range(2, n + 1):

result *= i

return result

编写一个函数get_input,接受用户输入的小丹和小伟每球获胜的概率以及模拟的比赛场次,并返回这三个值。

def get_input():

prob_a = float(input("请输入小丹每球获胜的概率(例如0.55): "))

prob_b = 1 - prob_a

num_games = int(input("请输入模拟的比赛场次(例如10000): "))

return prob_a, prob_b, num_games

编写一个函数sim_one_game,模拟一场比赛,接受小丹和小伟每球获胜的概率作为参数,返回比赛结束时双方的得分。

import random

def sim_one_game(prob_a, prob_b):

score_a = 0

score_b = 0

while not game_over(score_a, score_b):

if random.random() < prob_a:

score_a += 1

else:

score_b += 1

return score_a, score_b

def game_over(score_a, score_b):

return score_a >= 21 or score_b >= 21

编写一个函数sim_n_games,模拟多场比赛,接受小丹和小伟每球获胜的概率以及模拟的比赛场次作为参数,返回双方获胜的场次数。

def sim_n_games(prob_a, prob_b, num_games):

wins_a = 0

wins_b = 0

for _ in range(num_games):

score_a, score_b = sim_one_game(prob_a, prob_b)

if score_a > score_b:

wins_a += 1

else:

wins_b += 1

return wins_a, wins_b

编写一个函数print_summary,接受双方获胜的场次数以及模拟的比赛场次作为参数,打印输出比赛结果的汇总。

def print_summary(wins_a, wins_b, num_games):

print(f"总模拟场次: {num_games}")

print(f"小丹获胜概率: {wins_a / num_games * 100:.2f}%")

print(f"小伟获胜概率: {wins_b / num_games * 100:.2f}%")

第六章 函数相关习题

习题一:函数定义与调用

题目:

考虑如下函数定义 function(x, *y, **z),并有如下调用 function(*list('ABC'), 'd', **{'name': 'Sarah', 'age': 18})。请问这段代码是否会报错?如果不会报错,那么输出的结果是什么?

答案:

这段代码不会报错,输出结果为:

x: ay: (‘B’, ‘C’, ‘d’)z: {‘name’: ‘Sarah’, ‘age’: 18}

习题二:函数编程改进

题目:

假设有一个乒乓球比赛模拟函数,原始规则为:当某一方得分达到21分时即获胜。现需对函数进行以下改进:

增加容错功能,当输入的获胜概率不在0到1之间时,提示输入错误并要求重新输入。修改获胜规则:当某一方得分达到21分且与对手分差至少为2分时才可获胜。将比赛规则改为三局两胜制,率先赢得两局者获胜。

请简述如何实现上述改进。

答案:

使用while True循环不断接收输入,直到输入正确的获胜概率为止。修改获胜条件判断逻辑,确保不仅达到21分,还需与对手分差至少为2分。引入两个计数器分别记录双方赢下的局数,当任意一方赢下两局时结束比赛。

习题三:Lambda表达式的应用

题目:

给定一段文本字符串,使用lambda表达式对其进行字符频次统计,并按降序排列。

答案:

首先统计每个字符出现次数,存入字典中;然后利用sorted()函数结合lambda表达式,按照字典value值从大到小排序,具体实现为sorted(d.items(), key=lambda item: item[1], reverse=True)

习题四:Lambda表达式的特性与争议

题目:

简述Python中lambda表达式的三个特性,并谈谈你对lambda表达式在Python社区存在争议的看法。

答案:

匿名性:lambda表达式没有显式的名称。输入输出:由lambda关键字引导参数列表,冒号后跟随返回值表达式。简单性:只能包含简单的表达式,无法执行复杂语句(如for/while)。

关于争议,一方面lambda可以使某些场景下的代码更为简洁明了,另一方面若过度使用可能导致代码可读性下降,因此应根据实际情况合理选用。

Posted in 14年巴西世界杯
Previous
All posts
Next