【发布时间】:2020-05-28 01:55:52
【问题描述】:
所以我是 Python 新手,需要一些时间来适应的一个概念是列表理解。我已经读到,如果使用得当,它们可以提高计算速度,而且如果你要以正确的方式学习 Python,它们是非常了解的。
我正在编写一个程序来实现粒子聚合算法,该算法涉及将多达 10^6 个粒子累积到一个不断增长的集群中。我将回顾我的代码以尽可能优化性能,并且我有以下功能:
def step_all_walkers(walkers):
updated_positions = []
for walker in walkers:
decision = random.randint(1,4)
if decision == 1:
updated_walker = (min(walker[0]+1, N-1), walker[1])
elif decision == 2:
updated_walker = (max(walker[0]-1, 1), walker[1])
elif decision == 3:
updated_walker = (walker[0], min(walker[1] + 1, N-1))
elif decision == 4:
updated_walker = (walker[0], max(walker[1]-1, 1))
updated_positions.append(updated_walker)
return updated_positions
此函数使每个粒子(或我在代码中称其为 walker)在随机方向上走一个单位长度的步长,并防止粒子离开 N x N 网格。我注意到我正在创建并返回一个新列表updated_positions,并且由于这个列表和输入walker 列表可能非常大,我对列表推导的了解告诉我这可能是使用一个列表的好时机.然而,在这个问题的其他一些帖子中,只有一个 if/else 需要评估,人们回答说只使用一种好的 ole 时尚 for 循环。
那么我有几个问题:
1) 可以在列表推导中完成多个 if/elif 语句吗?
2) 把这个 for 循环写成列表理解有意义吗?这样做有什么好处吗?
我问这个问题的主要目的是建立更多的直觉,了解何时适合列表推导,以及看看这个函数是否可以提高效率。
【问题讨论】:
-
1.可以链接多个 if-表达式,但在我看来这看起来很难看。 2. 列表推导也创建了一个新列表。所以你不会在这里获得清晰和效率。
-
列表推导式也会生成一个新列表,所以我认为那里没有什么好处。对于内存大小,我什至不会担心几个 10^6 整数/整数元组的列表。你上面的代码很清楚。如果您想尝试列表推导,您可以创建一个覆盖案例并返回新位置并在列表推导中调用该函数的“移动”函数,但我认为您不会获得任何性能提升。
-
您可以使用函数字典来选择更新函数,然后您可以将列表理解编写如下:
return [update_map[randint(1,4)](walker) for walker in walkers]