首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python生成器

Python生成器
EN

Stack Overflow用户
提问于 2014-07-11 19:32:58
回答 3查看 1.5K关注 0票数 0

我试图在很多教程中理解Python生成器,他们告诉我们,它们比迭代列表要快得多,所以我尝试一下,我编写了一个简单的代码。我没想到时差会这么大,有人能解释一下为什么吗?或者我做错了什么。

代码语言:javascript
运行
复制
def f(limit):
    for i in range(limit):
        if(i / 7.0) % 1 == 0:
            yield i

def f1(limit):
    l = []
    for i in range(limit):
        if(i / 7.0) % 1 == 0:
            l.append(i)
    return l


t = timeit.Timer(stmt="f(50)", setup="from __main__ import f")
print t.timeit()

t1 = timeit.Timer(stmt="f1(50)", setup="from __main__ import f1")
print t1.timeit()

结果:t= 0.565694382945 t1 =11.9298217371

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-11 19:39:37

您没有公平地比较ff1

您的第一个测试只是测量构建生成器对象所需的时间。但是,它从不对这个对象进行迭代,这意味着f中的代码从未实际执行过(生成器只在迭代时执行它们的代码)。

然而,第二个测试测量调用f1所需的时间。也就是说,它计算函数构建列表l、运行for-循环到完成、多次调用list.append、然后返回结果所需的时间。显然,这比仅仅生成生成器对象要慢得多。

为了进行公平的比较,通过将生成器f转换为一个列表来耗尽它:

代码语言:javascript
运行
复制
t = timeit.Timer(stmt="list(f(50))", setup="from __main__ import f")

这将导致它被完全迭代,这意味着f中的代码现在将被执行。

票数 4
EN

Stack Overflow用户

发布于 2014-07-11 19:39:39

您正在计时创建生成器对象所需的时间。创建一个代码实际上并不会执行任何代码,因此您实际上是在选择一种精心设计的方法来不做任何事情。

修复之后,您会发现,当运行到完成时,生成器通常会稍微慢一些。它们的优点是,它们不需要同时将所有元素存储在内存中,并且可以中途停止。例如,当您有一个布尔值序列,并希望检查其中任何一个值是否为真时,首先使用列表计算所有值并创建它们的列表,然后再检查是否为真,而使用生成器则可以:

  • 创建第一个布尔值
  • 检查它是否是真的,如果是的话,停止创建布尔人
  • 否则,创建第二个布尔值
  • 检查一下是否是真的,如果是的话,停止制造布尔人
  • 诸若此类。
票数 1
EN

Stack Overflow用户

发布于 2014-07-11 19:47:34

https://wiki.python.org/moin/Generators在改进性能部分有一些很好的信息。虽然创建生成器可能需要一些时间,但它提供了许多优点。

  • 内存更少。通过一个一个地创建值,整个列表永远不会在内存中。
  • 开始的时间少了。创建一个完整的列表需要时间,而生成器可以在创建第一个值时立即使用。
  • 发电机没有设定的结束点。

下面是关于创建生成器和迭代器http://sahandsaba.com/python-iterators-generators.html的一个很好的教程。看看这个!

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

https://stackoverflow.com/questions/24705197

复制
相关文章

相似问题

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