【Py】递归和生成器组合使用

我们知道理论上使用循环方式构建列表都可以通过生成器替代
以生成斐波那契数列为例

def fib(max):
    n, a, b = 0, 0, 1
    fib_list = []
    while n < max:
        fib_list.append(b)
        a, b = b, a + b
        n = n + 1
    return fib_list

fib(10)
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1

list(fib(10))

但递归中要怎么用生成器呢?

以获取接口所有分页数据为例
递归+生成器:

def get_all_itmes():
    url = 'https://reqres.in/api/users'

    # 递归取下一页数据
    def get_next_page(pindex):
        # 获取数据
        # 生成params
        params = {
            'page':pindex
        }

        # 发送请求
        result = requests.get(url, params=params, verify=True)
        result_json = result.json()
        if result_json['data'] != []:
            for item in result_json['data']:
                yield item
            yield from get_next_page(pindex+1)

    # 启动
    return list(get_next_page(1))

%timeit get_all_items()
2.1 s ± 521 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
3.27 s ± 1.16 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
1.88 s ± 11.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

单纯递归:

def get_all_itmes():
    url = 'https://reqres.in/api/users'
    data_list = []

    # 递归取下一页数据
    def get_next_page(pindex):
        # 获取数据
        # 生成params
        params = {
            'page':pindex
        }

        # 发送请求
        result = requests.get(url, params=params, verify=True)
        result_json = result.json()
        if result_json['data'] != []:
            for item in result_json['data']:
                data_list.append(item)
            get_next_page(pindex+1)

    get_next_page(1)
    return data_list

%timeit get_all_items()
2.96 s ± 201 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
3.08 s ± 374 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
3.02 s ± 598 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

总结:生成器由于没有使用列表来存储数据,故理论上更快且更节省内存,但此处由于网络IO时间占比更大,所以速度提升不明显,但为了显得代码更高级,更推荐使用递归和生成器的组合。

参考:https://segmentfault.com/a/1190000018208997

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值