017~022 函数 课后练习题

017~022 函数 课后练习题17 函数 Python 的乐高积木 测试题 0 你有听说过 DRY 吗 DRY 是程序员们公认的指导原则 Don t Repeat Yourself 快快武装你的思维吧 拿起函数 不要再去重复拷贝一段代码了 1 都是重复一段代码

大家好,我是讯享网,很高兴认识大家。

17 函数:Python的乐高积木



测试题:

0.你有听说过DRY吗?

1.都是重复一段代码,为什么我要使用函数(而不使用简单的拷贝黏贴)呢?

     0) 可以降低代码量(调用函数只需要一行,而拷贝黏贴需要N倍代码)
     1) 可以降低维护成本(函数只需修改def部分内容,而拷贝黏贴则需要每一处出现的地方都作修改)
     2) 使程序更容易阅读(没有人会希望看到一个程序重复一万行“I love FishC.com”)

2.函数可以有多个参数吗?

        可以的,理论上你想要有多少个就可以有多少个,只不过如果函数的参数过多,在调用的时候出错的机率就会大大提高,因而写这个函数的程序员也会被相应的问候祖宗,所以,尽量精简吧,在Python的世界里,精简才是王道!

4.请问这个函数有多少个参数?

def MyFun((x, y), (a, b)): return x * y - a * b 

讯享网

【答案】 

        如果你回答两个,那么恭喜你错啦,答案是0,因为类似于这样的写法是错误的
        我们分析下,函数的参数需要的是变量,而这里你试图用“元祖”的形式来传递是不可行的。
        我想你如果这么写,你应该是要表达这么个意思:

讯享网>>> def MyFun(x, y): return x[0] * x[1] - y[0] * y[1] >>> MyFun((3, 4), (1, 2)) 10 

5.请问调用以下这个函数会打印什么内容?

>>> def hello(): print('Hello World!') return print('Welcome To FishC.com!') 

【答案】

讯享网>>> hello() Hello World! 

【答案解析】因为当Python执行到return语句的时候,Python认为函数到此结束,需要返回了(尽管没有任何返回值)。


动动手:

0.编写一个函数power()模拟内建函数pow(),即power(x, y)为计算并返回x的y次幂的值。

【自己写的!!】

def power(x, y): return xy 

【参考答案】

讯享网def power(x, y): result = 1 for i in range(y): result *= x return result 

 【回顾】对于该题【result *= x】

        1.对于【-=】或【+=】,首先要提前规定一个量【sum = 0】
           对于【*=】,首先要规定一个量【sum = 1】

        2.对于【for i in range(y):】,后面不用出现【i】,系统自动会计算i次:

>>> sum = 0 >>> for i in range(10): sum += 1 print(sum) 1 2 3 4 5 6 7 8 9 10
讯享网>>> result = 1 >>> for i in range(3): result *= 4 print(result) 4 16 64

1.编写一个函数,利用欧几里得算法(脑补链接)求最大公约数,例如gcd(x, y)返回值为参数x和参数y的最大公约数。

def gcd(x, y): while y: t = x % y x = y y = t return x print(gcd(4, 6)) 

2.编写一个将十进制转换为二进制的函数,要求采用“除2取余”(脑补链接)的方式,结果与调用bin()一样返回字符串形式。

讯享网def Dec2Bin(dec): temp = [] result = '' while dec: quo = dec % 2 dec = dec // 2 temp.append(quo) while temp: result += str(temp.pop()) return result print(Dec2Bin(62)) 

018 函数:灵活即强大



测试题:

1.函数写注释有什么不同?

      给函数写文档是为了让别人可以更好的理解你的函数,所以这是一个好习惯:

>>> def MyFirstFunction(name): '函数文档在函数定义的最开头部分,用不记名字符串表示' print('I love FishC.com!') 

 我们看到在函数开头写下的字符串Ta是不会打印出来的,但Ta会作为函数的一部分存储起来,这个我们称之为函数文档字符串,Ta的功能跟注释是一样的。函数的文档字符串可以按如下方式访问:

讯享网>>> MyFirstFunction.__doc__ '函数文档在函数定义的最开头部分,用不记名字符串表示' #另外,我们用help()来访问这个函数也可以看到这个文档字符串: >>> help(MyFirstFunction) Help on function MyFirstFunction in module __main__: MyFirstFunction(name) 函数文档在函数定义的最开头部分,用不记名字符串表示 

        建议使用help 


4. 默认参数和关键字参数表面最大的区别是什么?

【参考答案】

        关键字参数是在函数调用的时候,通过参数名制定需要赋值的参数,这样做就不怕因为搞不清参数的顺序而导致函数调用出错。
        而默认参数是在参数定义的过程中,为形参赋初值,当函数调用的时候,不传递实参,则默认使用形参的初始值代替。

 

动动手:

019 函数:我的地盘听我的



0. 编写一个符合以下要求的函数:

def mFun(*param, base=3): result = 0 for each in param: result += each result *= base print('结果是:', result) mFun(1, 2, 3, 4, 5, base=5) 

【笔记】
        细品,基数都不会求和,当base没有指定为5时默认为3,使用默认参数
        若base为5,则需要覆盖掉原来默认参数为3


 1. 寻找水仙花数 题目要求:如果一个3位数等于其各位数字的立方和,则称这个数为水仙花数。

        例如153 = 1^3+5^3+3^3,因此153是一个水仙花数。编写一个程序,找出所有的水仙花数。

讯享网def Narcissus(): for each in range(100, 1000): temp = each sum = 0 while temp: sum = sum + (temp%10) 3 temp = temp // 10 # 注意这里用地板除 if sum == each: print(each, end='\t') print("所有的水仙花数分别是:", end='') Narcissus() 

2.编写一个函数 findstr(),该函数统计一个长度为 2 的子字符串在另一个字符串中出现的次数。

def findstr(source,sub): ans=0 for i in range(len(source)): if source[i]==sub[0] and source[i+1]==sub[1]: ans+=1 return ans 

020 函数:内嵌函数和闭包



测试题:

0.【复习】如果希望在函数中修改全局变量的值,应该使用什么关键字?__global 关键字:

讯享网>>> count = 5 >>> def MyFun(): global count count = 10 print(count) >>> MyFun() 10 >>> count 10 
>>> count = 5 >>> def MyFun(): count = 10 print(count) >>> MyFun() 10 >>> count 5 '''没有加gobal,如果对全局变量进行修改函数会启动shadowing来保护全局变量, 在内部创建一个同名的局部变量''' 

1.【复习】在嵌套的函数中,如果希望在内部修改外部函数的局部变量,应该使用什么关键字?__nonlocal关键字:

讯享网>>> def Fun1(): x = 5 def Fun2(): nonlocal x#没有这个 调用fun1会报错 x *= x return x return Fun2() >>> Fun1() 25 

2. 【复习】Python 的函数可以嵌套,但要注意访问的作用域问题哦,请问以下代码存在什么问题呢?

def outside(): print('I am outside!') def inside(): print('I am inside!') inside() 

【解释】使用嵌套函数要注意一点就是作用域问题,inside() 函数是内嵌在 outside() 函数中的,在外边或者别的函数体里是无法对其进行调用的。
 【正确写法】:

讯享网def outside(): print('I am outside!') def inside(): print('I am inside!') inside() outside() 

3. 请问为什么代码 A 没有报错,但代码 B 却报错了?应该如何修改?

代码A:


讯享网

def outside(): var = 5 def inside(): var = 3 print(var) inside() outside() 

代码B:

讯享网def outside(): var = 5 def inside(): print(var) var = 3 inside() outside() 

【原因分析】 
        这里 outside() 函数里有一个 var 变量,但要注意的是,内嵌函数 inside() 也有一个同名的变量,Python 为了保护变量的作用域,故将 outside() 的 var 变量屏蔽起来,因此此时是无法访问到外层的 var 变量的。
【正确写法】:

def outside(): var = 5 def inside(): nonlocal var print(var) var = 3 inside() outside() 


4. 请问如何访问 funIn() 呢?

讯享网def funOut(): def funIn(): print('宾果!你成功访问到我啦!') return funIn() #返回的是函数finIn的返回值 这样会执行一次funIn 

【访问方式】只需要直接调用 funOut() 即可

funOut() 宾果!你成功访问到我啦!

5. 请问如何访问 funIn() 呢?

讯享网def funOut(): def funIn(): print('宾果!你成功访问到我啦!') return funIn #少了括号 相当于返回内嵌函数的引用 和第4不同它不会执行funIn

【访问方式】区别于上一题,这里返回的是一个函数对象,那么你就需要用 funOut()() 访问啦:

funOut()() 宾果!你成功访问到我啦!

【#】当然你也可以“曲线救国”:

讯享网go = funOut() go() 宾果!你成功访问到我啦!

6. 以下是“闭包”的一个例子,请你目测下会打印什么内容?

def funX(): x = 5 def funY(): nonlocal x #把x声明为非局部变量 x += 1 return x return funY a = funX()#a是一个函数对象 print(a()) print(a()) print(a()) 

【答案】当a=funX()的时候,只要a变量没有被重新赋值,funX()就没有被释放,也就是说局部变量x就没有被重新初始化,所以当全局变量不适用的时候,可以考虑使用闭包更稳定和安全
打印出:

讯享网6 7 8

动动手:

1. 请用已学过的知识编写程序,找出小甲鱼藏在下边这个长字符串中的密码,密码的埋藏点符合以下规律:

str1 = '''ASDASdFSDFdFDSFdGSDGVDd'''

【参考答案】

讯享网countFront = 0 # 统计前边的大写字母 countMid = 0 # 统计中间小写字母 countRear = 0 # 统计后边的大写字母 length = len(str1) target="" for i in range(length): if str1[i] == '\n': continue if str1[i].isupper(): if countMid: countRear+=1 if countRear==4: countRear=3 else: countFront+=1 if countFront==4: countFront=3 if str1[i].islower(): if countMid: countFront = 0 countMid = 0 countRear = 0 else: countMid=1 target=str1[i] if countFront==3 and countRear==3: print(target) countFront = 3 countMid = 0 countRear = 0

021 函数:lambda表达式



 1.请将下边的匿名函数转变为普通的*丝函数。

lambda x : x if x % 2 else None #三目操作符

【参考答案】

讯享网def is_odd(x): if x % 2: return x else: return None 

【笔记】
        对于【 if x % 2:】,如果【 if x % 2 == 0】,则不符合规定,执行【return None】。依此原理可以找出奇数。


3. 你可以利用filter()和lambda表达式快速求出100以内所有3的倍数吗?

【参考答案】

lambda x : x if x % 3 else None

【*丝函数形式】

讯享网def fun(x): if x%3==0: return 1 else: return 0 list(filter(fun,list(range(0,100)))) 

4. 还记得列表推导式吗?完全可以使用列表推导式代替filter()和lambda组合,你可以做到吗?

[i for i in range(0,100) if i%3==0] #注意和正常的for循环不同 这里不用冒号了 

5. 还记得zip吗?使用zip会将两数以元祖的形式绑定在一块,例如:

讯享网>>> list(zip([1, 3, 5, 7, 9], [2, 4, 6, 8, 10])) [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)] 

但如果我希望打包的形式是灵活多变的列表而不是元祖,(希望是[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]这种形式),你能做到吗?(采用map和lambda表达式)

【参考答案】

>>> list(map(lambda x, y : [x, y], [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])) [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] 

6. 请目测以下表达式会打印什么?

讯享网def make_repeat(n): return lambda s : s * n double = make_repeat(2) print(double(8)) print(double('FishC')) 

【自己做的!】

double = make_repeat(2) #返回一个s=2*s的函数 print(double(8)) #返回16 print(double('FishC')) #返回FishCFishC

022 函数:递归是神马

        递归,函数调用本身这么一个行为



 1. 递归必须满足哪两个基本条件?

【答案】
        
(1)函数调用自身
        (2)设置了正确的返回条件

2. 思考一下,按照递归的特性,在编程中有没有不得不使用递归的情况?

【答案】
        
例如汉诺塔,目录索引(因为你永远不知道这个目录里边是否还有目录),快速排序(二十世纪十大算法之一),树结构的定义等如果使用递归,会事半功倍,否则会导致程序无法实现或相当难以理解。

3. 用递归去计算阶乘问题或斐波那契数列是很糟糕的算法,你知道为什么吗?

        “普通程序员用迭代,天才程序员用递归”这句话是不无道理的。
        但是你不要理解错了,不是说会使用递归,把所有能迭代的东西用递归来代替就是“天才程序员”了,恰好相反,如果你真的这么做的话,那你就是“乌龟程序员”啦。
        为什么这么说呢?不要忘了,递归的实现可以是函数自个儿调用自个儿,每次函数的调用都需要进行压栈、弹栈、保存和恢复寄存器的栈操作,所以在这上边是非常消耗时间和空间的。
        另外,如果递归一旦忘记了返回,或者错误的设置了返回条件,那么执行这样的递归代码就会变成一个无底洞:只进不出!所以在写递归代码的时候,千万要记住口诀:递归递归,归去来兮!出来混,总有一天是要还的

4. 请聊一聊递归的优缺点(无需官方陈词,想到什么写什么就可以)

优点:

(1)递归的基本思想是把规模大的问题转变成规模小的问题组合,从而简化问题的解决难度(例如汉诺塔游戏)。
(2)有些问题使用递归使得代码简洁易懂(例如你可以很容易的写出前中后序的二叉树遍历的递归算法,但如果要写出相应的非递归算法就不是初学者可以做到的了。)

缺点:

(1)由于递归的原理是函数调用自个儿,所以一旦大量的调用函数本身空间和时间消耗是“奢侈的”(当然法拉利也奢侈,但还是很多人趋之若鹜)。
(2)初学者很容易错误的设置了返回条件,导致递归代码无休止调用,最终栈溢出,程序崩溃。

动动手 :

0.递归编写一个 power() 函数模拟内建函数 pow(),即 power(x, y) 为计算并返回 x 的 y 次幂的值。

讯享网 def pow(x,y): if y==1: return x else: return x*pow(x,y-1) 

1. 使用递归编写一个函数,利用欧几里得算法求最大公约数,例如 gcd(x, y) 返回值为参数 x 和参数 y 的最大公约数

 def gcd(x,y): if x%y==0: return y else: return gcd(y,x%y) 
小讯
上一篇 2025-04-04 14:50
下一篇 2025-03-25 17:58

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/43088.html