首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在这两个例子中,生成器在内存方面的优势是什么?

在这两个例子中,生成器在内存方面的优势是什么?
EN

Stack Overflow用户
提问于 2021-08-08 09:12:15
回答 3查看 57关注 0票数 1

生成器的优势之一是它使用更少的内存和消耗更少的资源。也就是说,我们不会一次生成所有数据,也不会为所有数据分配内存,并且每次只生成一个值。存储变量的状态、状态和值​​,实际上可以通过调用代码继续来停止和恢复代码。

我写了两个代码,我正在比较它们,我看到生成器可以正常编写,现在我看不到生成器的任何点。谁能告诉我这个生成器与正常编写时相比有什么优势?它们的每次迭代都会生成一个值。

第一个代码:

代码语言:javascript
复制
def gen(n):
    for i in range(n):
        i = i ** 2
        i += 1
        yield i

g = gen(3)
for i in g:
    print(i)

第二个问题:

代码语言:javascript
复制
def func(i):
    i = i ** 2
    i += 1
    return i

for i in range(3):
    print(func(i))

我知道gid是恒定的,而func(i)id是在变化的。

这就是主生成器优势的含义吗?

EN

回答 3

Stack Overflow用户

发布于 2021-08-08 09:25:41

具体地说,您在问题中提到的上述代码在内存方面没有区别,但第一种方法更可取,因为您需要的所有东西都在同一个生成器函数中,而在第二种情况下,循环和函数位于两个不同的位置,每次需要使用第二个函数时,您都需要在外部使用循环,这会不必要地增加冗余。

实际上,你写的两个函数,生成器函数和普通函数,它们不是等价的。在生成器中,您将返回所有值,即循环位于生成器函数内部:

代码语言:javascript
复制
def gen(n):
    for i in range(n):
        i = i ** 2
        i += 1
        yield i

但是,在第二种情况下,您只返回一个值,并且循环位于函数外部:

代码语言:javascript
复制
def func(i):
    i = i ** 2
    i += 1
    return i

为了使第二个函数等同于第一个函数,您需要在函数中包含循环:

代码语言:javascript
复制
def func(n):
    for i in range(n):
        i = i ** 2
        i += 1
        return i

现在,当然,如果控制进入循环内部,上面的函数总是为i=0返回一个值,所以要解决这个问题,你需要返回一个完整的序列,这要求你有一个列表或类似的数据结构,允许你存储多个值:

代码语言:javascript
复制
def func(n):
    result = []
    for i in range(n):
        i = i ** 2
        i += 1
        result.append(i)
    return result

for v in func(3):
    print(v)
    
1
2
5

现在,您可以清楚地区分这两种情况,在第一种情况下,每个值都会按顺序进行计算,然后再进行处理,即printed,但在第二种情况下,在实际处理之前,您最终会将整个结果保存在内存中。

票数 1
EN

Stack Overflow用户

发布于 2021-08-08 09:19:50

主要的优点是当你有一个大型数据集的时候。它基本上是lazy loading的思想,这意味着除非需要,否则不会调用数据。这节省了您的资源,因为通常在列表中,整个内容是一次性加载的,如果数据足够大,这可能会占用大量的主内存。

票数 0
EN

Stack Overflow用户

发布于 2021-08-08 09:25:11

第一个代码的优点是关于您没有显示的东西。一次生成和使用一个值比首先生成所有值,然后将它们收集到一个列表中,然后从列表中使用它们所需的内存更少。

要与第一个代码进行比较的第二个代码应该是:

代码语言:javascript
复制
def gen2(n):
    result = []
    for i in range(n):
        i = i ** 2
        i += 1
        result.append(i)
    return result

g = gen2(3)
for i in g:
    print(i)

请注意,如何使用gen2的结果与第一个示例中的gen的结果完全相同,但是如果n越来越大,gen2将使用更多内存,而无论n有多大,gen都将使用相同数量的内存。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68699333

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档