P18 017函数:Python的乐高积木 部分习题学习笔记
希望能通过这个帖子记录自己学习本课课后习题的复盘过程。题目:
动动手 1. 编写一个函数,利用欧几里得算法(脑补链接)求最大公约数,例如 gcd(x, y) 返回值为参数 x 和参数 y 的最大公约数
答案和自己的分析如下:
def gcd(x, y):
while y:
t = x % y
x = y
y = t
return x
'''
拿 gcd(5, 2)举例:
初始x = 5, y = 2
第一次循环
t = x % y = 5 % 2 = 1
x = y = 2
y = t = 1
第二次循环(因为此时y值为1)
t = x % y = 2 % 1 = 0
x = y = 1
y = t = 0
不进入第三次循环因为此时y = 0
返回x值 即 1
即5和2的最大公约数为1
分析答案代码,目的是自己写代码时,能反向推导写出这些代码:
1.代码顺序很重要,例如
x = y 写在前面
y = t 写在后面
这样可以保证下一轮被除数x 赋值为本轮循环的除数,
同时下一轮循环的除数y 赋值为本轮循环的余数
反过来写的话就不能实现这个结果了
2.为什么while y:
原因参考上方例子gcd(5, 2)的第二次循环
循环开始时y = 1,循环结束时 y 被赋值为当前余数的值 0, 符合题目要求:
“以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数”
同时 while y 可以保证不进行下一次循环,返回值,也符合题目要求。
'''
上一题中自己的分析思路和答案都不搭边儿,就不写自己的思路了。。{:5_99:} 题目: 动动手 2. 编写一个将十进制转换为二进制的函数,要求采用“除2取余”(补脑链接)的方式,结果与调用 bin() 一样返回字符串形式。
自己的分析如下:
'''
网上查到题目的具体要求为
十进制整数转换为二进制整数
十进制整数转换为二进制整数采用"除2取余,逆序排列"法。
具体做法是:用2整除十进制整数,可以得到一个商和余数;
再用2去除商,又会得到一个商和余数,如此进行,直到商为小于1时为止,
然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。
'''
#先不考虑逆序排列,先把函数大概框架做出来
def chu2(x):
shang = 1 #先定义变量shang
yushu = 0 #先定义变量yushu
while shang: #当商不为0时进行循环,也控制了当商为0时结束循环,即题目要求的“直到商为小于1时为止”
python语法中, / 是除法,例如:2/3 = 0.6666。而//是表示向下取整的除法,例如3//2=1,6.0//4 = 1。
也就是说 / 返回的是浮点类型的结果, 而 // 返回的是整数结果(可以理解为/的整数部分)
print('本轮循环开始时x值为', x)
shang = x // 2 #把x向下取整进行除法得到商复制给变量shang
print('代码运行到这里商值为', shang)
yushu = x % 2 #x除以2得余数复制给变量yushu
print('代码运行到这里余数值为', yushu)
x = shang #把本轮循环中的商值赋值给下轮循环的被除数x
print('本轮循环结束时, x值为', x)
print()
return
加入print的目的是为了看清楚每次循环中各个变量当时的值。
跑了一下,框架成了.. WilsonWolf2333 发表于 2020-1-6 15:25
题目: 动动手 2. 编写一个将十进制转换为二进制的函数,要求采用“除2取余”(补脑链接)的方式,结果与调 ...
然后我尝试加入列表来把余数放在一起, 加入翻转
def chu2(x):
shang = 1 #先定义变量shang
yushu = 0 #先定义变量yushu
list1 = [] #点定义一个空列表
while shang: #当商不为0时进行循环,也控制了当商为0时结束循环,即题目要求的“直到商为小于1时为止”
'''python语法中, / 是除法,例如:2/3 = 0.6666。而//是表示向下取整的除法,例如3//2=1,6.0//4 = 1。
也就是说 / 返回的是浮点类型的结果, 而 // 返回的是整数结果(可以理解为/的整数部分)'''
print('本轮循环开始时x值为', x)
shang = x // 2 #把x向下取整进行除法得到商复制给变量shang
print('代码运行到这里商值为', shang)
yushu = x % 2 #x除以2得余数复制给变量yushu
print('代码运行到这里余数值为', yushu)
x = shang #把本轮循环中的商值赋值给下轮循环的被除数x
print('本轮循环结束时, x值为', x)
list1.append(yushu) #把本轮循环的余数添加进列表尾部
print('余数列表当前为', list1)
print()
list1.reverse() #将余数列表翻转
return list1
运行结果为:
运行结果为:
>>> chu2(6)
本轮循环开始时x值为 6
代码运行到这里商值为 3
代码运行到这里余数值为 0
本轮循环结束时, x值为 3
余数列表当前为
本轮循环开始时x值为 3
代码运行到这里商值为 1
代码运行到这里余数值为 1
本轮循环结束时, x值为 1
余数列表当前为
本轮循环开始时x值为 1
代码运行到这里商值为 0
代码运行到这里余数值为 1
本轮循环结束时, x值为 0
余数列表当前为
WilsonWolf2333 发表于 2020-1-6 15:27
然后我尝试加入列表来把余数放在一起, 加入翻转
运行结果为:
下一个问题是思考如何把列表显示为为二进制数的110
查到“P17 016序列!序列!”里有 str(obj)的语法,把obj对象转换为字符串
不能用这个语法,因为 str(list1)的结果为''.
网上查到有join的语法,但是实际操作有报错
列出网上查到的join方法:
字符串对象的方法join其描述如下:
大概意思是:s.join(iterable)是将括号内的迭代对象(如列表)使用s字符串作为链接将迭代对象中的元素拼接成一个字符串,
返回该字符串。
卡住进行不下去了,准备看答案了。 本帖最后由 WilsonWolf2333 于 2020-1-7 16:18 编辑
WilsonWolf2333 发表于 2020-1-6 15:28
下一个问题是思考如何把列表显示为为二进制数的110
查到“P17 016序列!序列!”里有 str(obj) ...
答案如下,我尝试加注释目的是更好的理解答案的代码:
def Dec2Bin(dec):
temp = [] #建立空列表目的是把余数放到一个列表里
result = '' #建立空字符串,目的是可以用pop方法把字符串最后一个元素放在字符串里
while dec: #直到dec等于0时结束循环,即当商小于1时为止
quo = dec % 2 #除2得到的余数 赋值给变量quo
dec = dec // 2 #除2得到的商 复制给变量dec,“再用2去除商”
temp.append(quo) #把余数按顺序放在列表里
while temp: #????
'''查笔记找到P12里 - pop()从列表中取出最后一个元素并返回,
网上查到的是:pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。
语法:list.pop(obj=list[-1]) //默认为 index=-1,删除最后一个列表值。
obj -- 可选参数,要移除列表元素的对象。
该方法返回从列表中移除的元素对象。
'''
result += str(temp.pop()) #用加号拼接两个字符串,网上有文章说尽量少用+拼接字符串, 一会儿试试用join的方法修改代码
return result #返回转换成二进制的数字的字符串???
print(Dec2Bin(62))
注释里有两个带???的疑问,分别是:
1.while temp: 是什么操作?
2.return result 我理解会返回'1001011'这样的字符串,但是为什么返回的是整型的数值?
正在研究中。。。 WilsonWolf2333 发表于 2020-1-6 17:31
答案如下,我尝试加注释目的是更好的理解答案的代码:
正在查询上述第2个疑问,百度搜索的关键字为 “Python return 返回值”。
顺便发现了另一个问题:
def test2():
return 4, 'test2', ['dog', 'cat'], {"name": "John"}
运行函数得到的结果为:
>>> test2()
(4, 'test2', ['dog', 'cat'], {'name': 'John'})
>>>
为什么又自动加上了括号?元组?{:5_100:}
课后题剩余任务:
A.弄懂上述两个疑问
B.核对自己代码,看看卡在哪里 WilsonWolf2333 发表于 2020-1-6 17:55
正在查询上述第2个疑问,百度搜索的关键字为 “Python return 返回值”。
顺便发现了另一个问题:
上述第一个疑问"1.while temp: 是什么操作?” 有答案了。
从另一个帖子 @captainlyx 的回复里得到了启发, “在Python中,一般情况下,都是默认为True的,所以像这种情况,个人认为是,While的为真的条件都是执行的。相反,只有在,none,false0 () {}[]时才是假的,才不执行”。
当进行到while temp:这一行语句时, temp列表已经不为空了,所以布尔值为真,那么一定会进入这个循环。
但是这里为什么要加while temp: ? 如果不加的话,也会进行下方语句啊? 打算开个新帖咨询这个问题,连同第14课课后题while 1: 一起问。 WilsonWolf2333 发表于 2020-1-7 13:59
上述第一个疑问"1.while temp: 是什么操作?” 有答案了。
从另一个帖子 @captainlyx 的回复里得到了 ...
想到为什么加while temp:了 --
目的是控制循环什么时候结束。
因为这行代码: result += str(temp.pop()) 除了把temp列表最后一个元素放入result字符串中,也把temp列表每次移除最后一个元素。当最终temp经过这行代码最终 == []时,就不进行下次循环了。 (因为boor() == False)
我觉得这个疑问算是解决了。 WilsonWolf2333 发表于 2020-1-6 17:31
答案如下,我尝试加注释目的是更好的理解答案的代码:
继续研究问题2,思考过程如下:
这个函数
def Result(x):#新建一个测试返回值的函数
result = '' #模拟答案建立空字符串
list1 = #模拟答案建立最终余数列表
while list1: #开始循环和控制循环结束
result += str(list1.pop())#把列表list1的元素逆序排列放在字符串result中
return result
print(Result(1))#随便带入个变量x进入函数,反正对结果没影响哈哈哈
打印出来的结果是
1101
>>>
而运行完上述代码,在IDLE中输入Result(1)按回车,结果如下:
>>> Result(1)
'1101'
>>>
所以关于第二个疑问,现在变成了“print(Dec2Bin(62))结果为什么会显示函数返回值的整型数值"? 本帖最后由 WilsonWolf2333 于 2020-1-8 17:04 编辑
WilsonWolf2333 发表于 2020-1-7 16:44
继续研究问题2,思考过程如下:
这个函数
我觉得第二个问题也算是解决了。
也就是说当把这个函数的返回值赋给另一个变量a, a = Dec2Bin(62), 那么实际上a = '111110'.
print('str') 会省去引号。
参考资料:
1.百度搜索“python print return”这样的关键字,其中一篇博客提到:“在执行函数的时候return无法打印出值,return返回的结果只能用于给变量赋值。而print则可以直接打印。”
2.另一篇文章中提到:“在交互式idle下面编译执行的话return是有返回的,脚本执行时return才没有返回,以上说的都是脚本执行”。
3.另另一篇文章,提到:“print()函数,生成可读性更好的输出, 它会省去引号并打印”。
P.S.运行Result(x)代码后,在交互式idle里的如下测试也基本解释清楚了这个问题:
>>> a = Result(1)
>>> a
'1101'
>>> print(a)
1101
>>>
剩余任务 - 看7#楼,明天继续。{:5_108:} WilsonWolf2333 发表于 2020-1-6 17:55
正在查询上述第2个疑问,百度搜索的关键字为 “Python return 返回值”。
顺便发现了另一个问题:
>>> test2()
(4, 'test2', ['dog', 'cat'], {'name': 'John'})
>>>
我觉得自己弄明白这个问题了,的确是元组。因为:
def test2():
return 4, 'test2', ['dog', 'cat'], {"name": "John"}
返回值各元素之前加了逗号,那么返回值就是元组。
查询P14课堂笔记得到“元组的标志性符号就是逗号”。
交互式IDLE里如下测试也证明了这个问题:
>>> a = 1,2#把1,2这样的内容赋值给变量a
>>> a
(1, 2) 本帖最后由 WilsonWolf2333 于 2020-1-8 17:30 编辑
核对自己写的代码后,最终修改如下:
def chu2(x):
shang = 1 #先定义变量shang
yushu = 0 #先定义变量yushu
list1 = [] #点定义一个空列表
str1 = '' #定义空字符串,目的是把余数放到这个字符串里
while shang: #当商不为0时进行循环,也控制了当商为0时结束循环,即题目要求的“直到商为小于1时为止”
'''python语法中, / 是除法,例如:2/3 = 0.6666。而//是表示向下取整的除法,例如3//2=1,6.0//4 = 1。
也就是说 / 返回的是浮点类型的结果, 而 // 返回的是整数结果(可以理解为/的整数部分)'''
print('本轮循环开始时x值为', x)
shang = x // 2 #把x向下取整进行除法得到商复制给变量shang
print('代码运行到这里商值为', shang)
yushu = x % 2 #x除以2得余数复制给变量yushu
print('代码运行到这里余数值为', yushu)
x = shang #把本轮循环中的商值赋值给下轮循环的被除数x
print('本轮循环结束时, x值为', x)
list1.append(yushu) #把本轮循环的余数添加进列表尾部
print('余数列表当前为', list1)
print()
while list1: #造成循环,而且控制当list为空时终止循环
str1 += str(list1.pop()) #每次循环都把list1列表最后一个元素去除,同时返回这个元素的值,拼接进str1字符串中
print('当前余数字符串为',str1)
return str1
print(chu2(5))
总结如下:
1.上述代码中加入一些print语句目的是运行过程中看到各个变量当时的值
2.当时自己编代码时忘记了list.pop()这个语法
3.通过上述盖楼加深了对函数等基础语法的理解
以上就是负基础小白白白学习这一课的过程,感谢FC提供的这个平台!{:5_106:}
页:
[1]