Python3, 映射函数
Python3, 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() 更快,但它返回一个地图对象。地图对象应包含作为浮点数的总和。
我可以从地图对象中取出浮点数吗?
谢谢!
它更快,因为它什么都不做;如果是,那将行不通。
>>> 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
应用于 可迭代对象的每个元素 的结果,在此case 是生成器表达式 (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
但是你没有具体说明你真正在什么约束下操作,所以很难知道你真正的问题是什么。
我试图在 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() 更快,但它返回一个地图对象。地图对象应包含作为浮点数的总和。
我可以从地图对象中取出浮点数吗?
谢谢!
它更快,因为它什么都不做;如果是,那将行不通。
>>> 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
应用于 可迭代对象的每个元素 的结果,在此case 是生成器表达式 (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
但是你没有具体说明你真正在什么约束下操作,所以很难知道你真正的问题是什么。