Python:如何只获得具有合理性能的嵌套int列表的正数

时间:2013-11-08 22:34:14

标签: python performance list

我的代码可能很慢:

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

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

3 个答案:

答案 0 :(得分:3)

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

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

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

基于以下评论,我认为值得分析此代码的各种版本,包括map()filter()和生成器表达式,以查看最快的内容。

然而,有一百万个子列表,你只能这么做。

答案 1 :(得分:2)

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

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

但是如果你愿意超越加速Python,那么有三个很大的选择:

  • 并行化代码。运行四个进程,每个进程转换原始列表的四分之一。它应该快4倍。
  • 使用NumPy和/或Pandas之类的东西来矢量化代码。当你进行简单的算术运算(比如> 0)时,Python循环开销很容易比实际工作慢10倍,所以这可以给你10倍的加速。 (毋庸置疑,这是作弊 - 我假设您的数据结构无法更改,然后我更改了它。但是如果转换是一个微不足道且明显的转换 - 例如,来自固定形状的2D数组表示为列表将列表表示为固定形状的2D数组,表示为ndarray,值得作弊。)
  • 编译代码,无论是用Cython而不是Python编写代码,还是在PyPy而不是CPython中运行代码。一般来说,这比NumPy的速度提高了一点(并且提前加速甚至更加难以预测),但它的工作量也少得多。

答案 2 :(得分: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)