Python 一般来说,哪一种更快,收益率还是追加?

Python 一般来说,哪一种更快,收益率还是追加?,python,performance,return,generator,yield,Python,Performance,Return,Generator,Yield,我目前在一个个人学习项目中,在那里我阅读XML数据库。我发现自己正在编写收集数据的函数,我不确定什么是返回数据的快速方法 这通常更快: 收益率s,或 函数中有几个append()s,然后返回随后的列表 我很乐意知道在什么情况下,yields会比append()s快,反之亦然。yield具有懒惰的巨大优势,速度通常不是使用它的最佳理由。但如果它在您的环境中起作用,那么就没有理由不使用它: # yield_vs_append.py data = range(1000) def yielding()

我目前在一个个人学习项目中,在那里我阅读XML数据库。我发现自己正在编写收集数据的函数,我不确定什么是返回数据的快速方法

这通常更快:

  • 收益率
    s,或
  • 函数中有几个
    append()
    s,然后
    返回随后的
    列表

  • 我很乐意知道在什么情况下,
    yield
    s会比
    append()
    s快,反之亦然。

    yield
    具有懒惰的巨大优势,速度通常不是使用它的最佳理由。但如果它在您的环境中起作用,那么就没有理由不使用它:

    # yield_vs_append.py
    data = range(1000)
    
    def yielding():
        def yielder():
            for d in data:
                yield d
        return list(yielder())
    
    def appending():
        lst = []
        for d in data:
            lst.append(d)
        return lst
    
    结果是:

    python2.7 -m timeit -s "from yield_vs_append import yielding,appending" "yielding()"
    10000 loops, best of 3: 80.1 usec per loop
    
    python2.7 -m timeit -s "from yield_vs_append import yielding,appending" "appending()"
    10000 loops, best of 3: 130 usec per loop
    

    至少在这个非常简单的测试中,
    yield
    比append快。

    我最近问了自己一个类似的问题,探索通过追加到列表或通过生成器生成列表(或元组)的所有排列的方法,并发现(对于长度为9的排列,生成大约需要一秒钟):

    • 朴素的方法(排列是列表、附加到列表、返回列表列表)花费的时间大约是
      itertools的三倍
    • 使用发电机(即
      产量
      )可将其降低约20%
    • 使用生成器生成元组是最快的,大约是itertools.permutations的两倍
    少说废话!计时和分析非常有用:

    if __name__ == '__main__':
        import cProfile
        cProfile.run("main()")
    

    TH4Ck的屈服()还有一个更快的替代品。这是列表理解

    In [245]: def list_comp():
       .....:     return [d for d in data]
       .....:
    
    In [246]: timeit yielding()
    10000 loops, best of 3: 89 us per loop
    
    In [247]: timeit list_comp()
    10000 loops, best of 3: 63.4 us per loop
    

    当然,在不知道代码结构的情况下对这些操作进行微基准测试是相当愚蠢的。它们在不同的情况下都很有用。例如,如果您想要应用可以表示为单个表达式的简单操作,则列表理解非常有用。对于您来说,将遍历代码隔离到生成器方法中具有显著的优势。哪一个是合适的取决于使用情况。

    首先你必须决定,如果你需要发电机,这也得到了改进的方法。类似于列表生成器“[somethink中元素的元素]”。若在某些操作中仅使用列表中的值,则建议使用生成器。但是,如果您需要列表进行许多更改,并且同时处理许多元素,则必须使用列表。 (如果标准程序员使用列表,70%的情况下,生成器会更好。使用更少的内存,只是许多人看不到列表的其他方式。不幸的是,在我们这个时代,许多人对良好的操作化嗤之以鼻,只是为了工作。)

    若你们使用列表生成器来提高收益率,那个么让我们对收益率的人也这样做。无论如何,我们在Python编程语言中为所有操作提供了多个更优化的方法

    收益率比回报率要快,我会证明这一点。 看看这些家伙:

    data = range(1000)
    
    def yielder():
        yield from data
    
    def appending():
        L = []
        app = list.append
        for i in data:
            app(L, i)
        return L
    
    def list_gen():
        return [i for i in data]
    
    当然,附加比其他想法要慢,因为我们可以在任何循环时间创建和扩展列表。只是循环“for”是非常不正式的,如果你能避免这个,就这样做。因为在任何一步,这个函数都会加载下一个元素并写入我们的变量,从而在内存中获得这个对象值。所以我们跳转到任何元素,创建引用,在循环中扩展列表(声明的方法是极速optymalizer),当我们生成刚刚返回的结果时,summary在两个列表中得到了2000个元素

    list_gen的内存更少,我们只返回元素,但像up一样,我们生成secound list。现在我们有两份名单,原始数据和她的副本。概述2000个要素。在这里,我们避免了创建变量引用的步骤。因为我们的gen-in列表避免了这一步。只需编写元素

    我们使用最少的内存,因为我们刚刚从数据中得到了价值。我们避免一次提及。例如:

    data = range(1000)
    
    def yielder():
        yield from data
    
    def list_gen():
        return [i for i in data]
    
    #Now we generate next reference after line [i for i in data]
    for i in list_gen():
        #some instruction
    
    #This is our first reference, becouse was yield from data.
    for i in yielder():
        #some instruction
    
    对某些指令只使用一个元素,而不是全部从列表中,下一个值将在下一个循环中返回,而不是将所有1000个元素放入库中写入引用


    对于小挖掘主题,就在我无意中从谷歌搜索中发现了一个交叉点时,其他python初学者可以看出这一点。我实际上想包括列表理解,但我在这两个选项中进行选择:
    [n代表n,在func中,它产生()]
    [n代表n,在func中,它返回一个可编辑的()]
    。请注意,
    n
    可以是简单的元素解包,也可以是复杂的元素对元素的操作。不管怎样,这里有一个很好的观点:)懒惰意味着低内存需求吗?我为WKdm算法编写了一个压缩器/解压器。在分析一个函数之后,将位解压到列表中的函数是最慢的。我把它改装成发电机,速度更慢。yield版本提供大约22MB/s,append版本提供大约38MB/s。因此,这实际上取决于您正在执行的操作。
    lst.append
    lookup可能会减慢
    appending()
    。您可以在循环外部使用
    append=lst.append
    进行尝试。