骷揖学编程 发表于 2020-4-12 22:40:58

求问这种递归的运算逻辑?

小白求问各位大神,以下是论坛里一个Python的课后作业题
写一个函数get_digits(n),将参数n分解出每个位的数字并按顺序存放到列表中。举例:get_digits(123) ==>
#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是递归函数的一部分,每次运行到更深一层的逻辑时都会新建列表,且把该层产生的数字放入新列表,然后才把外层列表的元素追加到新列表后面。我觉得我这个解释应该算清楚吧{:10_254:}

leon_xinxin 发表于 2020-4-13 00:45:53

2里面的list列表是在递归最后一层才建立的

_2_ 发表于 2020-4-13 12:14:16

如果我没看错,这样应该就行:
def get_digits(n, /):
    return

_2_ 发表于 2020-4-13 12:22:27

本帖最后由 _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)

永恒的蓝色梦想 发表于 2020-4-13 12:22:40

_2_ 发表于 2020-4-13 12:14
如果我没看错,这样应该就行:

如果我没看错,这样不行

def get_digits(n, /):
    return

_2_ 发表于 2020-4-13 12:23:03

永恒的蓝色梦想 发表于 2020-4-13 12:22
如果我没看错,这样不行

……

永恒的蓝色梦想 发表于 2020-4-13 12:23:53

_2_ 发表于 2020-4-13 12:23
……

莫名其妙的split

_2_ 发表于 2020-4-13 12:24:03

永恒的蓝色梦想 发表于 2020-4-13 12:22
如果我没看错,这样不行

你少了一个 .split()

_2_ 发表于 2020-4-13 12:26:58

永恒的蓝色梦想 发表于 2020-4-13 12:23
莫名其妙的split

手撸代码不容易啊

永恒的蓝色梦想 发表于 2020-4-13 12:27:27

_2_ 发表于 2020-4-13 12:24
你少了一个 .split()

就是因为那个 split 你的代码错了

骷揖学编程 发表于 2020-4-13 12:55:04

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

哇,谢谢谢谢,想明白了{:5_110:}

骷揖学编程 发表于 2020-4-13 12:56:37

leon_xinxin 发表于 2020-4-13 00:45
2里面的list列表是在递归最后一层才建立的

嗯,明白了,谢谢谢谢!{:5_110:}

winhero 发表于 2020-4-13 12:57:12

本帖最后由 winhero 于 2020-4-13 13:04 编辑

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

第一层:digits(123) = digits(23) +

第二层:digits(23) = digits(3) +

第三层:digits(3) =

      总:digits(123) = + +

   于是:print(list1) 的结果就是

方法: 一层层去分析

启发: 每次调用 digits() 函数 list1 列表就会被重置为空列表

骷揖学编程 发表于 2020-4-13 13:03:17

_2_ 发表于 2020-4-13 12:22
def digits(n):
    length = len(str(n))
    list1 = []


大神,我还是想不通,第二位数追加到list末尾的话,顺序不是正好和原数相同吗?{:10_282:}

winhero 发表于 2020-4-13 13:12:13

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

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

list1 即 会被添加到最后,

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

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

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

winhero 发表于 2020-4-13 13:14:27

也就是说

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

print(list1) 的结果就是

骷揖学编程 发表于 2020-4-13 13:16:30

winhero 发表于 2020-4-13 12:57
关键在于: return digits(b)+list1

第一层:digits(123) = digits(23) +


嗯嗯,明白了,太感谢了!{:5_110:}
页: [1]
查看完整版本: 求问这种递归的运算逻辑?