美文网首页
递归函数遇到的一些坑

递归函数遇到的一些坑

作者: 阿登20 | 来源:发表于2021-04-04 14:23 被阅读0次

递归遇到的一些坑。

为什么递归函数会返回None

def calc(n,count):
    '''
    :param n: 需要进行递归的对象
    :param count: 计数器
    :return: 条件不成立时,返回最终值
    '''
    # print(n,count)
    if count < 5: #运行第五次时退出
        calc(n//2,count+1) #每一层接收它下一层的值,return必不可少,否则倒数第三层无法接收倒数第二层的返回值
    else:
        return n  # 在上一个return 递归函数被中止
f = calc(199,1)
print('res运算第五次时的结果:',f) # 输出>>res运算第五次时的结果: 12

def t(n):
    if n ==1:
        return n
    return t(n-1)   # 递归函数在 n=2在时候调用结束,这里不加return就会返回为None
print(t(4))

上面的例子:在调用递归处不加return 就会返回None.因为在递归结束处并没有返回值,所以默认返回None。当多加一个return是把下层的return返回回来,一层层返回,最后返回值才会是n

再看一个求列表叠加的例子

a = [1,5,7,9]
def sum(a):
    if isinstance(a, list) and len(a) >1:
        # return a[0] +sum(a[1:])
        a[0] +sum(a[1:])
    else:
       return  a[0]

如果注释处不加return 就会报错。因为递归处返回的是None None和int不能相加
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'       

1。 递归函数在for循环里面return,会结束for循环,所以不能在for循环里面return 递归函数 8行代码处。for循环自带递归 return

a = [1,3,4,["啊登","向佳","咸维维",[66,77]],[[15,19,["香蕉",["西瓜","芒果"]]],8,0]]
from collections.abc import Iterable
# 1。 递归函数在for循环里面return,会结束for循环,所以不能在for循环里面return 递归函数 8行代码处。for循环自带递归 return
def get_a(a):
    b = []
    for i  in a:
        if isinstance(i, Iterable) and (not isinstance(i, (str, bytes))): 
            return get_a(i)
            
        else:
            b.append(i)
    
    return b

  
print(get_a(a))   [66, 77]

可以发现 在for循环里面return 递归函数 最后得到的结果只有一组,以为 for循环遇到return终止了当前循环,比如a列表 [[15,19,["香蕉",["西瓜","芒果"]]]元素并没有循环到。那么怎么办呢? for 不加return呢?

a = [1,3,4,["啊登","向佳","咸维维",[66,77]],[[15,19,["香蕉",["西瓜","芒果"]]],8,0]]
def get_a(a):
    b = []
    for i  in a:
        if isinstance(i, Iterable) and (not isinstance(i, (str, bytes))):
            get_a(i)
        else:
            b.append(i)
    return b

print(get_a(a)) [1, 3, 4]

当调用get_a(i) 递归调用的时候,每一个列表for循环结束后会返回当前调用的返回值b,可以看出a对象里面有多个列表,那么递归调用就会返回多个返回值b. 这个每一次的返回值 并没有做整合处理。所以上面最后的返回值是 [1,3,4]

当递归遍历想要所有的结果的时候,不能在for循环里面return 递归函数。 for循环结束后return 可以接受递归一次的返回值。如果递归的每一次结果都要叠加到一起可以这么做:

  1. 如果返回值可以叠加操作,可以用 res += 递归调用。
  2. 如果递归返回值是列表,可以 列表.extend(递归调用)
    • 还有一种的就从外表传参给个空列表传给函数,函数用一个变量去接收这个空别表。 在递归调用处直接这样调用。fo(x,当前列表) x是参数, 当前列表第一次值是传过来的空列表。

案例1

import os
def count_dir_size(path):
    """"统计文件或者文件夹大小,返回的是字节"""
    count_size = 0
    if not os.path.isdir(path):
        return os.path.getsize(path)
    else:
        for f in os.listdir(path):
            new_path = os.path.join(path, f)
            if os.path.isfile(new_path):
                count_size = count_size + os.path.getsize(new_path)
            else:
                count_size = count_size + count_dir_size(new_path)

        return count_size

案例2 取出列表a所有的元素,放在一个新列表里面

a = [1,3,4,["啊登","向佳","咸维维",[66,77]],[[15,19,["香蕉",["西瓜","芒果"]]],8,0]]
def get_a(a):
    b = []
    for i  in a:
        if isinstance(i, Iterable) and (not isinstance(i, (str, bytes))):
            b.extend(get_a(i))
        else:
            b.append(i)
    return b
print(get_a(a))
[1, 3, 4, '啊登', '向佳', '咸维维', 66, 77, 15, 19, '香蕉', '西瓜', '芒果', 8, 0]

案例3 如果递归调用,对调用处不做任何处理,可以外部穿一个参数,比如空列表

a = [1,3,4,["啊登","向佳","咸维维",[66,77]],[[15,19,["香蕉",["西瓜","芒果"]]],8,0]]
def get_a(a,list_none):
    b = list_none
    for i  in a:
        if isinstance(i, Iterable) and (not isinstance(i, (str, bytes))):

            get_a(i, b)
        else:
            b.append(i)
    return b

print(get_a(a, []))

案例4 yield from 函数。去做处理

a = [1,3,4,["啊登","向佳","咸维维",[66,77]],[[15,19,["香蕉",["西瓜","芒果"]]],8,0]]
def get_a(a):
    for i  in a:
        if isinstance(i, Iterable) and (not isinstance(i, (str, bytes))):
            yield from get_a(i)
        else:
            yield i

print(list(get_a(a)))

相关文章

  • 递归函数遇到的一些坑

    递归遇到的一些坑。 为什么递归函数会返回None 上面的例子:在调用递归处不加return 就会返回None.因为...

  • Python语法-函数进阶篇

    主要是对函数的一些补充内容,包括递归函数,常见内置函数和常见的高阶函数的使用 递归函数 和所有语言一样,递归函数说...

  • 第二章 递归和回溯

    递归 递归的含义:任何调用自身的函数称为递归。用递归求解问题要点在于递归函数调用自身取解决一个规模比原始问题小一些...

  • Day10递归函数、模块、迭代器、生成器

    一、递归函数 1、什么是递归函数 在函数中调用函数本身的函数就是递归函数。 2、递归的作用 循环能做的递归都能做 ...

  • day11 函数(3)

    递归函数 实际开发的时候,能不用递归就不用 什么是递归函数 函数中调用函数本身的函数就是递归函数 递归的作用: 循...

  • python 递归函数

    递归函数 递归函数 : 在函数的调用自身 递归边界 : 退出递归的终止条件 例1,函数func如果没有设备递归边界...

  • day11-日常(递归函数、模块、迭代器、生成器)

    递归函数(实际开发的时候,能不用递归就不用) 1.什么是递归函数 函数中调用函数本身的函数就是递归函数 2.递归的...

  • 2019-01-07day11学习总结

    递归函数 实际开发的时候能不用递归就不用递归 1. 什么是递归函数 函数中调用函数本身的函数就是递归函数 2. 递...

  • 递归函数、模块、生成器、迭代器

    一、递归函数 实际开发的时候,能不用递归就不用 1.什么是递归函数 函数中调用函数本身的函数就是递归函数 2.递归...

  • day 11总结

    递归函数 实际开发的时候,能不用递归就不用1.什么是递归函数函数中调用函数本身的函数就是递归函数 2.递归的作用:...

网友评论

      本文标题:递归函数遇到的一些坑

      本文链接:https://www.haomeiwen.com/subject/tellkltx.html