python - 防止列表理解中的多次调用

标签 python list-comprehension

<分区>

使用下面的示例,我们可以看到 x.giveMyNum() 将被调用 4 次 - 3 次检查 myNum 的值,一次构建要返回的列表。您可能希望它只被调用 3 次,因为它是一个纯函数并且它的值不会改变。

列表理解版:

class test(object):
    def __init__(self,myNum):
        self.myNum=myNum
    def giveMyNum(self):
        print "giving"
        return self.myNum
q=[test(x) for x in range(3)]
print [x.giveMyNum() for x in q if x.giveMyNum()>1]

我知道你可以做这样的事情来修复它:

ret=[]
for x in q:
    k=x.giveMyNum()
    if k>1:
        ret.append(k)

但是有没有办法防止列表理解中的额外调用?

我不需要保留中间值。

最佳答案

您可以将它与生成器结合使用,但我会坚持使用常规循环。

print([n for n in (x.giveMyNum() for x in q) if n  > 1 ])

如果您喜欢函数式代码,您可以使用 python2 映射或 itertools.imap:

print([n for n in map(test.giveMyNum, q) if n > 1 ])

使用 python2 和 imap 比 gen exp 更快:

In [8]: q = [test(x) for x in range(10000)]

In [9]: timeit [ n for n in imap(test.giveMyNum, q) if n > 1]
1000 loops, best of 3: 1.94 ms per loop

In [10]: timeit [n for n in (x.giveMyNum() for x in q) if n  > 1 ]
100 loops, best of 3: 2.56 ms per loop

map 使用 python3 也更快:

In [2]: timeit [ n for n in map(test.giveMyNum, q) if n > 1]
100 loops, best of 3: 2.23 ms per loop

In [3]: timeit [n for n in (x.giveMyNum() for x in q) if n  > 1 ]
100 loops, best of 3: 2.93 ms per loop

常规循环和调用方法的时机:

In [8]: timeit [x.giveMyNum() for x in q if x.giveMyNum()>1]
100 loops, best of 3: 3.59 ms per loop

In [9]: %%timeit
ret=[]
for x in q:
    k=x.giveMyNum()
    if k>1:
        ret.append(k)
   ...: 
100 loops, best of 3: 2.67 ms per loop

Python3:

In [2]: %%timeit
ret=[]
for x in q:
    k=x.giveMyNum()
    if k>1:
        ret.append(k)
   ...: 
100 loops, best of 3: 2.84 ms per loop

In [3]: timeit [x.giveMyNum() for x in q if x.giveMyNum()>1]

100 loops, best of 3: 4.08 ms per loop

关于python - 防止列表理解中的多次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31442096/

相关文章:

python - 将字典列表转换为列表列表

python - 在 OS X 上将 MacPorts 安装的 Python 包与 Enthought(或其他一些)Python 一起使用?

python - 每个 ytick 有多个条形的水平条形图

python - 将 pandas 多索引 DataFrame 的列替换为另一个 DataFrame

python - 如何使用 matplotlib 绘制数组中的特定点?

python - 使用理解向列表添加元素

python - 不需要列表理解乘法

python - 将我的函数转换为一个类

Python:列表理解中某处出错了?

python - 元组列表(从元组中删除特殊项目)