python - 使用 List Comprehension 和/或 map 避免嵌套 for 循环
问题描述
几天来,我一直在努力优化(不仅让它看起来更好)3个嵌套循环,其中包含一个条件调用和一个函数调用。我现在拥有的是以下内容:
def build_prolongation_operator(p,qs):
'''
p: dimension of the coarse basis
q: dimension of the fine basis
The prolongation operator describes the relationship between
the coarse and fine bases:
V_coarse = np.dot(V_fine, I)
'''
q = sum(qs)
I = np.zeros([q, p])
for i in range(0, q):
for j in range(0, p):
for k in range(0, qs[j]):
# if BV i is a child of j, we set I[i, j] = 1
if i == f_map(j, k, qs):
I[i, j] = 1
break
return I
哪里f_map
是:
def f_map(i, j, q):
'''
Mapping which returns the index k of the fine basis vector which
corresponds to the jth child of the ith coarse basis vector.
'''
if j < 0 or j > q[i]:
print('ERROR in f_map')
return None
result = j
for k in range(0, i):
result += q[k]
return result
在分析我的整个代码时,我得到了build_prolongation_operator
45 次和f_map
大约850 万次的调用!
这是图片:
我试图对列表理解和地图做同样的事情,但没有任何运气。
以下是build_prolongation_operator
预期的输入示例:
p = 10
qs = randint(3, size=p)
解决方案
我不知道基数和延长运算符,但你应该关注算法本身。在优化方面,这几乎总是合理的建议。
这可能是症结所在——如果不是,它可以帮助您入门:f_map
计算不依赖于i
,但您正在为 的每个值重新计算它i
。由于i
范围从零到 中的值之和qs
,因此您将通过缓存结果来节省大量的重新计算;谷歌“python memoize”,它实际上会自己写。解决这个问题,你可能已经完成了,没有任何微优化。
您需要足够的空间来存储max(p) * max(qs[j])
值,但从您报告的调用次数来看,这应该不是太大的障碍。
推荐阅读
- c++ - C++ 指针与 std::vector:对长变量有任何影响吗?
- linux - yum + 当启用=0 时如何在 yum 中启用 repo
- embed - 将 Camunda 嵌入到现有的 Java 应用程序中
- pandas - 检测时间序列数据的急剧下降(熊猫)
- java - 找不到 Spring DriverManagerDataSource
- python - Python- 抓取 LinkedIn 名称
- reactjs - React Firebase图像网址未保存
- javascript - Google Apps 脚本 - 在动态更改选项卡编号上运行相同的代码
- bash - 递归地对文件中两个模式之间的行进行排序
- javascript - 赛普拉斯:每个都有内部承诺 - 打破循环