鱼C论坛

 找回密码
 立即注册
查看: 870|回复: 17

[已解决]求问这种递归的运算逻辑?

[复制链接]
发表于 2020-4-12 22:40:58 | 显示全部楼层 |阅读模式
1鱼币
小白求问各位大神,以下是论坛里一个Python的课后作业题
写一个函数get_digits(n),将参数n分解出每个位的数字并按顺序存放到列表中。举例:get_digits(123) ==> [1, 2, 3,]
#1
list1=[]
def digits(n):
    length = len(str(n))
    if n >= 10:
        a = n // 10**(length-1)#求首位数
        list1.append(a)
        b = n % 10**(length-1)#减去首位数,余下的数字
        return digits(b)+list1
    else:
        list1.append(n)
        return list1
digits(123)
print(list1)

#2
def digits(n):
    length = len(str(n))
    list1 = []
    if n >= 10:
        a = n // 10**(length-1)#求首位数
        list1.append(a)
        b = n % 10**(length-1)#减去首位数,余下的数字
        return digits(b)+list1
    else:
        list1.append(n)
        return list1
digits(123)
print(list1)

#1得到的是【1,2,3】,而#2得到的是【3,2,1】,我被搞糊涂了,第二种的运算逻辑是怎样的?为什么会倒过来?谢谢各位大神了!
最佳答案
2020-4-12 22:40:59
本帖最后由 倒戈卸甲 于 2020-4-12 23:43 编辑

因为list1声明的位置不一样,list声明在函数外部,那么递归从外层开始,就可以依次把百位数、十位数、个位数加入列表。但如果list是递归函数的一部分,每次运行到更深一层的逻辑时都会新建列表,且把该层产生的数字放入新列表,然后才把外层列表的元素追加到新列表后面。我觉得我这个解释应该算清楚吧

最佳答案

查看完整内容

因为list1声明的位置不一样,list声明在函数外部,那么递归从外层开始,就可以依次把百位数、十位数、个位数加入列表。但如果list是递归函数的一部分,每次运行到更深一层的逻辑时都会新建列表,且把该层产生的数字放入新列表,然后才把外层列表的元素追加到新列表后面。我觉得我这个解释应该算清楚吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-12 22:40:59 From FishC Mobile | 显示全部楼层    本楼为最佳答案   
本帖最后由 倒戈卸甲 于 2020-4-12 23:43 编辑

因为list1声明的位置不一样,list声明在函数外部,那么递归从外层开始,就可以依次把百位数、十位数、个位数加入列表。但如果list是递归函数的一部分,每次运行到更深一层的逻辑时都会新建列表,且把该层产生的数字放入新列表,然后才把外层列表的元素追加到新列表后面。我觉得我这个解释应该算清楚吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-13 00:45:53 | 显示全部楼层
2里面的list列表是在递归最后一层才建立的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-13 12:14:16 From FishC Mobile | 显示全部楼层
如果我没看错,这样应该就行:
def get_digits(n, /):
    return [int(i) for i in str(n).split()]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-13 12:22:27 From FishC Mobile | 显示全部楼层
本帖最后由 _2_ 于 2020-4-13 12:25 编辑

def digits(n):
    length = len(str(n))
    list1 = []
    if n >= 10:
        a = n // 10**(length-1)#求首位数
        list1.append(a)
        #问题就在上一行,求出首位数后, list.append() 追加,下一行又减去首位数,再 return 又是一个递归,导致第二位数会被追加到末尾,所以与原数的数字顺序相反

        b = n % 10**(length-1)#减去首位数,余下的数字
        return digits(b)+list1
    else:
        list1.append(n)
        return list1
digits(123)
print(list1)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-13 12:22:40 | 显示全部楼层
_2_ 发表于 2020-4-13 12:14
如果我没看错,这样应该就行:

如果我没看错,这样不行
def get_digits(n, /):
    return [int(i) for i in str(n)]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-13 12:23:03 From FishC Mobile | 显示全部楼层
永恒的蓝色梦想 发表于 2020-4-13 12:22
如果我没看错,这样不行

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

使用道具 举报

发表于 2020-4-13 12:23:53 | 显示全部楼层

莫名其妙的split
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-13 12:24:03 From FishC Mobile | 显示全部楼层
永恒的蓝色梦想 发表于 2020-4-13 12:22
如果我没看错,这样不行

你少了一个 .split()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-13 12:26:58 From FishC Mobile | 显示全部楼层
永恒的蓝色梦想 发表于 2020-4-13 12:23
莫名其妙的split

手撸代码不容易啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-13 12:27:27 | 显示全部楼层
_2_ 发表于 2020-4-13 12:24
你少了一个 .split()

就是因为那个 split 你的代码错了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-4-13 12:55:04 | 显示全部楼层
倒戈卸甲 发表于 2020-4-12 22:40
因为list1声明的位置不一样,list声明在函数外部,那么递归从外层开始,就可以依次把百位数、十位数、个位 ...

哇,谢谢谢谢,想明白了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-4-13 12:56:37 | 显示全部楼层
leon_xinxin 发表于 2020-4-13 00:45
2里面的list列表是在递归最后一层才建立的

嗯,明白了,谢谢谢谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-13 12:57:12 | 显示全部楼层
本帖最后由 winhero 于 2020-4-13 13:04 编辑

关键在于: return digits(b)+list1

第一层:digits(123) = digits(23) + [1]

第二层:digits(23) = digits(3) + [2]

第三层:digits(3) = [3]

      总:digits(123) = [3] + [2] + [1]

   于是:print(list1) 的结果就是 [3, 2, 1]

  方法: 一层层去分析

  启发: 每次调用 digits() 函数 list1 列表就会被重置为空列表
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-4-13 13:03:17 | 显示全部楼层
_2_ 发表于 2020-4-13 12:22
def digits(n):
    length = len(str(n))
    list1 = []

大神,我还是想不通,第二位数追加到list末尾的话,顺序不是正好和原数相同吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-13 13:12:13 | 显示全部楼层
骷揖学编程 发表于 2020-4-13 13:03
大神,我还是想不通,第二位数追加到list末尾的话,顺序不是正好和原数相同吗?

不是的,第一次调用 digits() 函数时

list1 即 [1] 会被添加到最后,

第二次,因为是 digits(b) + list1

所以,第二次调用 digits() 函数时

list1 会被添加到倒数第二位 即 digits(3) + [2] + [1]

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

使用道具 举报

发表于 2020-4-13 13:14:27 | 显示全部楼层
也就是说

把 return digits(b) + list1 改成 return list1 + digits(b) 的话

print(list1) 的结果就是 [1, 2, 3]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-4-13 13:16:30 | 显示全部楼层
winhero 发表于 2020-4-13 12:57
关键在于: return digits(b)+list1

第一层:digits(123) = digits(23) + [1]

嗯嗯,明白了,太感谢了!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-26 10:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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