鱼C论坛

 找回密码
 立即注册
查看: 2466|回复: 13

[学习笔记] P18 017函数:Python的乐高积木 部分习题学习笔记

[复制链接]
发表于 2020-1-6 13:20:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
希望能通过这个帖子记录自己学习本课课后习题的复盘过程。

题目:
动动手 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 可以保证不进行下一次循环,返回值,也符合题目要求。
'''

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-1-6 13:23:23 | 显示全部楼层
上一题中自己的分析思路和答案都不搭边儿,就不写自己的思路了。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-6 15:25:11 | 显示全部楼层
题目: 动动手 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的目的是为了看清楚每次循环中各个变量当时的值。
跑了一下,框架成了..
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-6 15:27:10 | 显示全部楼层
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
余数列表当前为 [0]

本轮循环开始时x值为 3
代码运行到这里商值为 1
代码运行到这里余数值为 1
本轮循环结束时, x值为 1
余数列表当前为 [0, 1]

本轮循环开始时x值为 1
代码运行到这里商值为 0
代码运行到这里余数值为 1
本轮循环结束时, x值为 0
余数列表当前为 [0, 1, 1]

[1, 1, 0]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-6 15:28:40 | 显示全部楼层
WilsonWolf2333 发表于 2020-1-6 15:27
然后我尝试加入列表来把余数放在一起, 加入翻转

运行结果为:

下一个问题是思考如何把列表[1, 1, 0]显示为为二进制数的110
查到“P17 016序列!序列!”里有 str(obj)的语法,把obj对象转换为字符串
不能用这个语法,因为 str(list1)的结果为'[1, 1, 0]'.

网上查到有join的语法,但是实际操作有报错
列出网上查到的join方法:
字符串对象的方法join其描述如下:
大概意思是:s.join(iterable)是将括号内的迭代对象(如列表)使用s字符串作为链接将迭代对象中的元素拼接成一个字符串,
返回该字符串。

卡住进行不下去了,准备看答案了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-6 17:31:11 | 显示全部楼层
本帖最后由 WilsonWolf2333 于 2020-1-7 16:18 编辑
WilsonWolf2333 发表于 2020-1-6 15:28
下一个问题是思考如何把列表[1, 1, 0]显示为为二进制数的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'这样的字符串,但是为什么返回的是整型的数值?
正在研究中。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-6 17:55:30 | 显示全部楼层
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'})
>>>
为什么又自动加上了括号?元组?

课后题剩余任务:
A.弄懂上述两个疑问
B.核对自己代码,看看卡在哪里
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-7 13:59:28 | 显示全部楼层
WilsonWolf2333 发表于 2020-1-6 17:55
正在查询上述第2个疑问,百度搜索的关键字为 “Python return 返回值”。
顺便发现了另一个问题:

上述第一个疑问"1.while temp: 是什么操作?” 有答案了。

从另一个帖子 @captainlyx 的回复里得到了启发, “在Python中,一般情况下,都是默认为True的,所以像这种情况,个人认为是,While的为真的条件都是执行的。相反,只有在,none,false  0   () {}  []时才是假的,才不执行”。

当进行到while temp:这一行语句时, temp列表已经不为空了,所以布尔值为真,那么一定会进入这个循环。
但是这里为什么要加while temp: ? 如果不加的话,也会进行下方语句啊? 打算开个新帖咨询这个问题,连同第14课课后题while 1: 一起问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-7 16:07:08 | 显示全部楼层
WilsonWolf2333 发表于 2020-1-7 13:59
上述第一个疑问"1.while temp: 是什么操作?” 有答案了。

从另一个帖子 @captainlyx 的回复里得到了 ...

想到为什么加while temp:了 --

目的是控制循环什么时候结束。
因为这行代码: result += str(temp.pop()) 除了把temp列表最后一个元素放入result字符串中,也把temp列表每次移除最后一个元素。当最终temp经过这行代码最终 == []时,就不进行下次循环了。 (因为boor() == False)

我觉得这个疑问算是解决了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-7 16:44:15 | 显示全部楼层
WilsonWolf2333 发表于 2020-1-6 17:31
答案如下,我尝试加注释目的是更好的理解答案的代码:

继续研究问题2,思考过程如下:
这个函数
def Result(x):  #新建一个测试返回值的函数
    result = '' #模拟答案建立空字符串
    list1 = [1, 0, 1, 1] #模拟答案建立最终余数列表
    while list1: #开始循环和控制循环结束
        result += str(list1.pop())  #把列表list1的元素逆序排列放在字符串result中

    return result
print(Result(1))  #随便带入个变量x进入函数,反正对结果没影响哈哈哈
打印出来的结果是
1101
>>>
而运行完上述代码,在IDLE中输入Result(1)按回车,结果如下:
>>> Result(1)
'1101'
>>>

所以关于第二个疑问,现在变成了“print(Dec2Bin(62))结果为什么会显示函数返回值的整型数值"?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-7 17:56:39 | 显示全部楼层
本帖最后由 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
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-7 17:58:32 | 显示全部楼层
剩余任务 - 看7#楼,明天继续。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-8 17:13:40 | 显示全部楼层
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)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-8 17:28:41 | 显示全部楼层
本帖最后由 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提供的这个平台!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-12 16:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表