我想用Python脚本中最快的方法过滤两个列表。我已经使用了内置的filter()方法来实现这个目的。但是它很慢,而且花费了太多的时间,因为我有一个非常大的列表,我想每个列表中超过500万个项目,或者可能更多。我不知道我将如何做。如果有人有想法,请为它写一个小函数。
filter()
zbsbpyhn1#
知道通常条件列表理解比相应的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
(Not我知道为什么我需要在timeit命名空间中放置f。我还没有真正使用过这个模块。)
timeit
djmepvbi2#
在用C语言做之前,你可以试试numpy,也许你可以把过滤变成数字运算。
ruyhziif3#
numbers = [-2, -1, 0, 1, 2] def extract_positive(numbers): positive_numbers = [] for number in numbers: if number > 0: # Filtering condition positive_numbers.append(number) return positive_numbers extract_positive(numbers)
bcs8qyzn4#
也许你的列表太大,内存放不下,你会遇到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是大卫M. Beazley编写的教程,讲述了 * 生成器 * 的一些有趣用法。
htzpubme5#
如果你能避免创建列表摆在首位,你会更高兴。而非
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
通过使用生成器,您不会在内存中保留太多内容。
dldeef676#
我想filter()是您不必用C编写过滤函数就能达到的最快速度(在这种情况下,您最好用C编写整个过滤过程)。为什么不粘贴您正在筛选的函数呢?这可能会导致更容易的优化。阅读this关于Python中的优化,以及this关于Python/C API。
dy1byipe7#
Filter会创建一个新的列表,所以如果你的原始列表很大,你可能会使用两倍的内存。如果你只需要迭代地处理结果,而不是把它作为一个真实的的随机访问列表,你可能更好地使用ifilter。
for x in itertools.ifilter(condition_func, my_really_big_list): do_something_with(x)
其他的速度提示是使用python内置函数,而不是你自己编写的函数。有一个itertools.ifilterfalse专门针对你需要引入lambda来否定你的检查的情况。(例如“ifilter(lambda x:而不是x.isalpha(),l)”,应该写成“ifilterfalse(字符串.isalpha,l)”)
7条答案
按热度按时间zbsbpyhn1#
知道通常条件列表理解比相应的lambda快得多可能是有用的:
(Not我知道为什么我需要在
timeit
命名空间中放置f。我还没有真正使用过这个模块。)djmepvbi2#
在用C语言做之前,你可以试试numpy,也许你可以把过滤变成数字运算。
ruyhziif3#
bcs8qyzn4#
也许你的列表太大,内存放不下,你会遇到thrashing。如果源代码在文件中,你不需要一次把整个列表都放进内存。试着使用 itertools,例如:
请注意,ifilter 返回一个快速且内存效率高的 * 迭代器 *。
Generator Tricks是大卫M. Beazley编写的教程,讲述了 * 生成器 * 的一些有趣用法。
htzpubme5#
如果你能避免创建列表摆在首位,你会更高兴。
而非
您可能需要查看列表中的函数。
那么你的过滤器就不会占用大量的内存
通过使用生成器,您不会在内存中保留太多内容。
dldeef676#
我想filter()是您不必用C编写过滤函数就能达到的最快速度(在这种情况下,您最好用C编写整个过滤过程)。
为什么不粘贴您正在筛选的函数呢?这可能会导致更容易的优化。
阅读this关于Python中的优化,以及this关于Python/C API。
dy1byipe7#
Filter会创建一个新的列表,所以如果你的原始列表很大,你可能会使用两倍的内存。如果你只需要迭代地处理结果,而不是把它作为一个真实的的随机访问列表,你可能更好地使用ifilter。
其他的速度提示是使用python内置函数,而不是你自己编写的函数。有一个itertools.ifilterfalse专门针对你需要引入lambda来否定你的检查的情况。(例如“ifilter(lambda x:而不是x.isalpha(),l)”,应该写成“ifilterfalse(字符串.isalpha,l)”)