python中的快速过滤方法

时间:2008-10-14 08:25:10

标签: python list filter

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

6 个答案:

答案 0 :(得分:14)

也许您的列表太大而且不适合内存,并且您遇到thrashing。 如果源位于文件中,则不需要同时在内存中存储整个列表。尝试使用 itertools ,例如:

from itertools import ifilter

def is_important(s):
   return len(s)>10

filtered_list = ifilter(is_important, open('mylist.txt'))

请注意, ifilter 会返回一个快速且内存效率高的迭代器

Generator Tricks是David M. Beazley的教程,教授生成器的一些有趣用法。

答案 1 :(得分:4)

如果您可以避免首先创建列表,那么您会更开心。

而不是

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

通过使用生成器,你不会在内存中留下太多东西。

答案 2 :(得分:2)

我想filter()的速度和你可能获得的速度一样快,而不必用C编写过滤函数(在这种情况下,你最好用C编写整个过滤过程)。

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

阅读有关Python优化的this。关于Python / C API的this

答案 3 :(得分:2)

过滤器将创建一个新列表,因此如果您的原始文件非常大,最终可能会使用最多两倍的内存。 如果您只需要迭代地处理结果,而不是将其用作真正的随机访问列表,那么最好使用它 而是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)”)

答案 4 :(得分:1)

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

答案 5 :(得分:1)

知道条件列表理解通常比相应的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命名空间中。那里没有真正使用过该模块。)