Python3,map-function

时间:2015-07-22 00:07:47

标签: python-3.x map-function

我正在尝试在python3中优化这段代码以获得速度(当然还有正确性):

from math import log
from timeit import Timer

def groffle_slow(mass, density):
    total = 0.0
    for i in range(10000):
        masslog = log(mass * density)
        total += masslog/(i+1)
    return total

我很惊讶map加速了多少,所以......

def groffle_faster(mass, density):
    total = 0.0
    masslog = log(mass * density)
    return map(sum, (masslog/(i+1) for i in range(10000)))

看看执行时间的差异,没有比较。 groffle_faster()更快,但它正在返回一个地图对象。 map对象应该包含float作为浮点数。

无论如何,我可以从地图对象中获取浮动?

谢谢!

1 个答案:

答案 0 :(得分:3)

它更快,因为它没有做任何事情;如果是的话,它就不会起作用。

>>> mass = 1.2
>>> density = 2.3
>>> masslog = math.log(mass * density)
>>> map(sum, (masslog/(i+1) for i in range(10000)))
<map object at 0x7feccaf1fc18>

这个map对象是一个惰性对象,它将产生应用于迭代的每个元素的函数sum的结果,在本例中是生成器表达式(masslog/(i+1) for i in range(10000))。没有进行任何计算。

但这无论如何都没有多大意义,因为您尝试将sum函数分别应用于每个元素 ,因此:

>>> list(map(sum, (masslog/(i+1) for i in range(10000))))
Traceback (most recent call last):
  File "<ipython-input-13-c0f9c805843a>", line 1, in <module>
    list(map(sum, (masslog/(i+1) for i in range(10000))))
TypeError: 'float' object is not iterable

你真正想要的只是

>>> sum(masslog/(i+1) for i in range(10000))
9.936677928893602

会给出

>>> %timeit groffle_slow(1.5, 2.5)
100 loops, best of 3: 5.08 ms per loop
>>> %timeit groffle_fast(1.5, 2.5)
100 loops, best of 3: 3.02 ms per loop

但由于sum(1/(i+1) for i in range(10000))是一个固定的数字,我不确定你为什么不简单地使用像

这样的东西
>>> def groffle_O1(mass, density):
...     MSUM = 9.787606036044345
...     return log(mass*density) * MSUM
... 
>>> %timeit groffle_O1(1.5, 2.5)
1000000 loops, best of 3: 424 ns per loop

但是你还没有明确规定你的实际操作限制,所以很难知道你的真正问题是什么。