这节课让我们来看一下上节课的习题答案吧。
上节课的题目有两道题,较多,我们来一题题地解答。
1. 主题: Duck, Duck, Goose!
假设你在一个家禽农场工作,需要计算从传送带传下来的动物数量(不要问为什么)。每一只鸭子(duck)价值1点。鹅(geese或者goose)比鸭子更大,所以它们每一只价值2点。鸡蛋(egg或者eggs)会重置你现在的计数变成0。举个栗子,一个序列 [“duck”, “duck”, “goose”]
会计数为4点(每个鸭子1点,一只鹅2点)。[“duck”, “goose”, “egg”, “duck”]
会得到1点(鸡蛋重置前面的所有计数变为0,最后一个鸭子为1点)。
请完成ddg()函数,只有一个参数,为一个字符串为元素的list。每一个字符串都是以下其中之一:“duck”,“goose”,“egg”(全部小写)。这个函数会根据前面所说的规则返回一个非负整数。
以下是你要实现的一些例子:
函数调用命令 | 返回值 |
---|---|
ddg(["goose", "duck", "duck", "duck"]) | 5 |
ddg(["duck", "egg", "goose", "egg"]) | 0 |
ddg(["duck", "duck", "egg", "goose"]) | 2 |
解析:看了题目之后,我们需要从返回值入手,先问问自己,最后返回什么,需要你算什么。于是找到需要返回一个统计点数的整数。而鸭,鹅和鸡蛋分别对应的点数是+1
,+2
,重置为0
。而计算机的编程思维是什么呢?是最笨的人计算的思维。思考一下,如果让你口头计算,你会怎么算,是不是一个个看list中的元素,然后在心里弄一个现在的和,来累加?没错,计算机也是这么想的。于是我们的思路就出来了,遍历读取,按顺序读取输入这个list参数中的每一个元素,每读取一个计算一下最新的返回结果,当读取完最后一个元素的时候就得到了最后的返回值了,进行返回即可。
就拿第二个ddg(["duck", "egg", "goose", "egg"])
返回值为0
作为例子吧。假设我们设定一个和变量sum
初始值为0
,第一个元素是“duck”
,那么这个sum就加上1,得到1
;第二个元素为“egg”
,立即重置sum为0
;第三个元素为“goose”
,sum加上2,得到2
;最后一个元素为“egg”
,则再次重置sum为0
。至此所有元素处理完毕,这时候sum=0
,返回结果:0
。
再来想如何遍历一个列表呢?使用for循环就可以做到。遍历列表中的每一个元素,然后对sum进行对应操作即可。最后整个循环结束后,我们再返回这个sum。
这道题还可以有别的思路,课后思考:你是否还能想出一种和我不一样的思路?
具体的完整代码我们在讲解完下一道题的时候再一起发布。
2. 主题:倒序排列约数
没错,这一次我们有两道题!请写一个factors()函数,传入一个正整数作为参数。这个函数会返回一个list,这个list包含了这个参数的所有约数(包括1和它自己,约数就是一个除数,用参数除以这个约数能够整除),并且这些约数是倒序排列的(从大到小排列)。比如说factors(24)
就会返回一个list:[ 24, 12, 8, 6, 4, 3, 2, 1 ]
。
小提示:list中有一个方法可以让list中的数字倒序排列,和append的调用方法一样,比如一个list的变量名为res,那么res.reverse()
就可以让这个list倒序排列。但是这道题,不使用reverse方法也能实现,你可以用两种方法来完成这道题,很有意思。
以下是你要实现的一些例子:
函数调用命令 | 返回值 |
---|---|
factors(38) | [38, 19, 2, 1] |
factors(128) | [128, 64, 32, 16, 8, 4, 2, 1] |
factors(17) | [17, 1] |
解析:这道题首要是先要理解什么是约数,这个概念部分同学或许还记得在学校里面学过。这里再重申一下,约数就是作为一个除数能被被除数整除的数。比如6除以2等于3没有余数,那么2就是6的约数。比如6除以4商为1,余数为2,余数不为0,那么4就不是6的约数。
那么如何从小到大检测一个数的约数呢?我们还是可以用for循环,比如之前学过的range函数可以生成一个数字序列,比如range(6)
可以生成从0到5的数字序列,每次我们的i取这个序列中的一个数字,然后+1
,不就是1到6了么?我们使用if判断被除数除以除数是否有余数,使用%
来求余数。我们如果从小到大检测,每检测到一个就使用append
方法加入返回的列表中,这样势必最后的列表是正序排列的,最后for循环结束后使用reverse
方法来倒序排列下就是我们的正确答案了。
如果不使用reverse方法呢?该怎么实现呢?这就涉及到我们上一种办法的关键步骤了,可以注意到,第一种方法我们检测约数是从小到大检测的,那么我们从大到小检测不就可以实现了?还是拿参数为6作为例子,range(6)
会生成0到5的序列,那么如果从大到小检测,我们需要检测的是6,5,4,3,2,1
这几个数字是否是6的约数,而循环变量比如i
第一次取的是0
,如何算出6呢?6 - 0 = 6
。因此,就用参数减去这个i就可以了。第二次i
取的是1
,6 - 1 = 5
,完美。最后i
取5
,6 - 5 = 1
,正好把6到1都检测完一遍,这时候得到的返回list直接就是倒序排列的了,就用不上reverse方法了。
让我们来看一下最终的代码:
def ddg(poultry): # 请把代码写到这里 sum = 0 for i in poultry: if i == "duck": sum = sum + 1 elif i == "goose": sum = sum + 2 else: sum = 0 return sum def factors(integer): # 请把代码写到这里 result = [] for i in range(integer): if integer % (i + 1) == 0: result.append(i + 1) result.reverse() # 方法2 result = [] for i in range(integer): if integer % (integer - i) == 0: result.append(integer - i) return result # 测试代码 ############### Part 1 Tests ############### print('Testing ddg() for ["goose", "duck", "duck", "duck"]: ' + str(ddg(["goose", "duck", "duck", "duck"]))) print('Testing ddg() for ["duck", "egg", "goose", "egg"]: ' + str(ddg(["duck", "egg", "goose", "egg"]))) print('Testing ddg() for ["duck", "duck", "egg", "goose"]: ' + str(ddg(["duck", "duck", "egg", "goose"]))) ############### Part 2 Tests ############### print('Testing factors() for value = 38: ' + str(factors(38))) print('Testing factors() for value = 128: ' + str(factors(128))) print('Testing factors() for value = 17: ' + str(factors(17)))
有什么问题吗?有问题的话欢迎在本篇文章下方跟帖留言!
本节课对应的视频教程:
在线观看:
高清源文件下载:
内容已经隐藏,请注册为本站会员后查看
感谢大家的收看,我们下期再见!
评论