【问题标题】:fast filter method in pythonpython中的快速过滤方法
【发布时间】:2010-09-17 01:18:30
【问题描述】:

我想在 python 脚本中使用任何最快的方法过滤两个列表。为此,我使用了内置的filter() 方法。但它很慢而且花费了太多时间,因为我有很大的列表,我认为每个列表中有超过 500 万个项目,或者可能更多。 我不知道我会怎么做。请如果有人有想法或为它编写小功能。

【问题讨论】:

    标签: python list filter


    【解决方案1】:

    我猜 filter() 是尽可能快的,而无需在 C 中编写过滤函数(在这种情况下,您最好在 C 中编写整个过滤过程)。

    为什么不粘贴要过滤的功能?这可能会导致更容易优化。

    阅读this 了解 Python 中的优化。还有this 关于 Python/C API。

    【讨论】:

    • 你的两个链接都失效了。
    【解决方案2】:

    也许您的列表太大,无法存储在内存中,您会遇到thrashing。 如果源文件在文件中,则不需要一次将整个列表都放在内存中。尝试使用 itertools,例如:

    from itertools import ifilter
    
    def is_important(s):
       return len(s)>10
    
    filtered_list = ifilter(is_important, open('mylist.txt'))
    

    请注意,ifilter 返回一个快速且内存高效的 iterator

    Generator Tricks 是 David M. Beazley 的教程,教授 generators 的一些有趣用途。

    【讨论】:

      【解决方案3】:

      在使用 C 之前,您可以尝试numpy。也许您可以将过滤变成数字运算。

      【讨论】:

        【解决方案4】:

        过滤器将创建一个新列表,因此如果您的原始列表很大,您最终可能会使用两倍的内存。 如果您只需要迭代处理结果,而不是将其用作真正的随机访问列表,则最好使用 ifilter 代替。即。

        for x in itertools.ifilter(condition_func, my_really_big_list):
            do_something_with(x)
        

        其他速度提示是使用 python 内置函数,而不是您自己编写的函数。有一个 itertools.ifilterfalse 专门用于 否则您需要引入 lambda 来否定您的检查的情况。 (例如“ifilter(lambda x: not x.isalpha(), l)”应该写成“ifilterfalse(str.isalpha, l)”)

        【讨论】:

          【解决方案5】:

          知道条件列表推导通常比相应的 lambda 快得多,这可能很有用:

          >>> import timeit
          >>> timeit.Timer('[x for x in xrange(10) if (x**2 % 4) == 1]').timeit()
          2.0544309616088867
          >>> timeit.f = lambda x: (x**2 % 4) == 1
          timeit.Timer('[x for x in xrange(10) if f(x)]').timeit()
          >>> 
          3.4280929565429688
          

          (不知道为什么我需要将 f 放在 timeit 命名空间中,那里。并没有真正使用过这个模块。)

          【讨论】:

          • 我只是比较了以下两行: [e for e in lst if e[1] in olist] # filter(lambda e: e[1] in olist, lst) 。 . .而且他们都花费了完全相同(令人痛苦的)时间。
          【解决方案6】:

          如果你能避免一开始就创建列表,你会更快乐。

          而不是

          aBigList = someListMakingFunction()
          filter( lambda x:x>10, aBigList )
          

          您可能想查看生成列表的函数。

          def someListMakingGenerator( ):
              for x in some source:
                  yield x
          

          那么您的过滤器不会占用大量内存

          def myFilter( aGenerator ):
              for x in aGenerator:
                  if x > 10: 
                      yield x
          

          通过使用生成器,您不会在内存中保留太多内容。

          【讨论】:

            猜你喜欢
            • 2010-12-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-11-26
            • 1970-01-01
            • 2012-09-01
            相关资源
            最近更新 更多