2

我的代码可能很慢:

onlyPositives = map ( (lambda mylist: [elem for elem in mylist if elem > 0]) , myintlist )

什么是快速的方法?(对于 100 万个大小为 50 整数的子列表)。

4

3 回答 3

3

单独定义函数而不是使用 alambda并使用列表推导而不是map()

def func(mylist):
    return [elem for elem in mylist if elem > 0]

onlyPositives = [func(e) for e in myintlist]

根据下面的评论,我认为值得分析这段代码的各种版本,包括map(),filter()和生成器表达式,看看什么是最快的。

但是,拥有一百万个子列表,您能做的只有这么多。

于 2013-11-08T22:36:06.503 回答
2

首先,我假设您的数据结构和算法无法改进。

在这种情况下,您的算法实现没有任何问题。正如 Simeon Visser 所指出的,可能有一些方法可以稍微降低开销,但在那里你能完成的只有这么多。

但是,如果您愿意超越加快 Python 的速度,还有三个大的选择:

  • 并行化代码。运行四个进程,并让每个进程转换原始列表的四分之一。它应该快近 4 倍。
  • 使用 NumPy 和/或 Pandas 之类的东西对代码进行矢量化。当您进行简单的算术运算(如 > 0)时,Python 循环开销很容易比实际工作慢 10 倍,因此这可以为您提供 10 倍的加速。(不用说,这是作弊——我假设你的数据结构不能改变,然后我改变了它。但如果转换是一个微不足道且显而易见的转换——例如,从一个表示为列表的固定形状的二维数组列表到一个固定形状的 2D 数组表示为ndarray,这是值得作弊的。)
  • 编译代码,无论是用 Cython 而不是 Python 编写,还是在 PyPy 而不是 CPython 中运行。一般来说,这给你的加速比 NumPy 少一点(而且加速比提前更不可预测),但它也少了很多工作。
于 2013-11-08T22:41:53.517 回答
0

这里有几种方法 - 第一种是您提供的方法。顺便说一句,函数调用在 CPython 中具有相对显着的开销。为了速度,你最好使用 pypy、numba 或 cython。如果你想继续使用朴素的 CPython,lambda 和 def 会减慢速度。

#!/usr/bin/python3

myintlist = [ [ 1, 2, 3, -1, -6, 0 ], [ 5, 6, 7, -4, 2, -6, 3, -6, 0, 10] ]
onlyPositives = map ((lambda mylist: [ elem for elem in mylist if elem > 0 ]), myintlist)
print(onlyPositives)

onlyPositives2 = []
for input_sublist in myintlist:
    output_sublist = (element for element in input_sublist if element > 0)
    onlyPositives2.append(output_sublist)
print(onlyPositives2)

# You could change the list comprehension to another generator expression if you want
onlyPositives3 = ([element for element in input_sublist if element > 0] for input_sublist in myintlist)
print(onlyPositives3)
于 2013-11-08T22:49:19.493 回答