在python中,可以使用列表理解来替换两个forloops来计算双和吗?

2024-04-25 23:59:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个双倍和,基本上

总和=exp(x^2+y^2)

当然,我可以简单地使用两个嵌套的for循环,但对于大数,这往往会很耗时。我可以使用一个列表理解来替换内部for循环,请参见此处:

import numpy as np

N_x      = 100
N_y      = 100

# straight forward way
result_1 = .0
for x in xrange(N_x):
    for y in xrange(N_y):
        result_1 += np.exp( (float(x)/N_x)**2 + ( (float(y)/N_y)**2 )

# using one list comprehension
result_2 = .0
for x in xrange(N_x):
    inner_loop = [ np.exp( (float(y)/N_y)**2 ) for y in range(N_y) ]
    result_2  += np.exp( (float(x)/N_x)**2 ) * sum(inner_loop)

但是如何将外部for循环替换为列表理解(我希望它更快),有什么提示吗?在


Tags: inimportnumpyloop列表forasnp
3条回答
result = sum(np.exp(x**2 + y**2) for x in range(N_x) for y in range(N_y))

你就快到了。完整和可以写成两个1D和的乘积,即(sum exp x^2) * (sum exp y^2)

>>> import numpy as np                      
>>>                       
>>> N_x = N_y = 100                                      
>>> 
# brute force                         
>>> result_1 = .0
>>> for x in xrange(N_x):
...     for y in xrange(N_y):
...         result_1 += np.exp( (float(x)/N_x)**2 + (float(y)/N_y)**2 )
... 
>>> result_1
21144.232143358553
>>> 
# single product method
>>> from __future__ import division
>>> 
>>> x, y = np.arange(N_x) / N_x, np.arange(N_y) / N_y
>>> np.exp(x*x).sum() * np.exp(y*y).sum()
21144.232143358469

我猜这是你甚至可以用列表比较和击败暴力纽比的方法:

^{pr2}$

实际上,在Python3中进行计时是因为我不知道如何在Python2中使用timeit

>>> from timeit import repeat
>>> 
>>> kwds = dict(globals=globals(), number=100)
>>> 
# single product - list comp
>>> repeat('sum(np.exp(rx*x*x) for x in range(N_x)) * sum(np.exp(ry*y*y) for y in range(N_y))', **kwds)
[0.0166887859813869, 0.016465034103021026, 0.016357041895389557]
>>>
# numpy brute force
>>> repeat('np.exp(np.add.outer(x*x, y*y)).sum()', **kwds)
[0.07063774298876524, 0.0348161740694195, 0.02283189189620316]

显然,numpy单品速度更快

>>> repeat('np.exp(x*x).sum() * np.exp(y*y).sum()', **kwds)
[0.0031406711786985397, 0.0031003099866211414, 0.0031157969497144222]

你为什么不用裸体的方式。。。无回路:

x = np.arange(N_x)
y = np.arange(N_y)

xx, yy = np.meshgrid(x, y)
result = np.sum(np.exp((xx/N_x)**2 + (yy/N_y)**2))

相关问题 更多 >