零基础学python 12 程序不枯燥:for循环结构(课后习题答案)

avatar 2017年4月21日20:35:33 评论 1,446

这节课让我们来看一下上节课的习题答案吧。

上节课的题目有两道题,较多,我们来一题题地解答。

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取的是16 - 1 = 5,完美。最后i56 - 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)))

 

有什么问题吗?有问题的话欢迎在本篇文章下方跟帖留言!

本节课对应的视频教程:

在线观看:

 

高清源文件下载:

内容已经隐藏,请注册为本站会员后查看

 

 

感谢大家的收看,我们下期再见!

avatar

发表评论

您必须才能发表评论!