在Python列表理解中使用多个ifelif语句。

问题描述 投票:0回答:1

所以我是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 

这个函数让每一个粒子(或步行者,我在代码中称他们为 "步行者")向随机方向迈出单位长度的一步,并防止粒子从N×N的网格中走出来。我注意到,我正在创建并返回一个新的列表。updated_positions,而且由于这个列表和输入的 walker 列表可能非常大,我对列表理解的了解告诉我,这可能是使用列表理解的好时机。然而,在其他一些关于这个问题的帖子中,当只有一个ifelse需要被评估时,人们回答说只要使用一个好的时尚的for循环就可以了。

那么我有几个问题。

1)多个ifelif语句可以在列表理解中完成吗?

2)把这个for循环写成list comprehension有意义吗?这样做有什么好处吗?

我问这个问题的主要目的是为了建立更多的直觉,知道什么时候适合用list comprehension,同时也想看看是否可以用list comprehension让这个函数更有效率。

python list-comprehension
1个回答
1
投票

我会把它变成一个查找字典开始,然后你可能会考虑一个列表理解法

decisions = {1: lambda walker: (min(walker[0]+1, N-1), walker[1])}
return [decisions[random.randint(1,4)](walker) for walker in walkers]

0
投票

一个案例,其中 列表理解法 是当逻辑太复杂的时候。

For循环就比较简单了,因为它允许。

  • 包括注释来解释代码
  • 使用控制流关键字,如继续。
  • 使用日志语句或断言更容易调试的部分。
  • 允许其他人通过向下扫描行轻松地看到逻辑的复杂性。

然而,正如Sayse所建议的那样,我们通常可以通过额外的数据结构和帮助函数来简化逻辑,从而实现列表理解。

不使用ifelse语句的列表理解法 (需要逻辑旁路)

def step_all_walkers(walkers, N):
  def decision(walker):
    " Helper function for making a decisions "
    # Place decision choices into a data structure
    options = [
      lambda walker: (min(walker[0]+1, N-1), walker[1]),
      lambda walker: (max(walker[0]-1, 1), walker[1]),
      lambda walker: (walker[0], min(walker[1] + 1, N-1)),
      lambda walker: (walker[0], max(walker[1]-1, 1))]

    while True:
      n = random.randint(0, 3)  # use rather than (1, 4) to 
                                # provide proper index into options
      yield options[n](walker)

# Now, list comprehension is straight forward to follow
return [decision(walker) for walker in walkers]
© www.soinside.com 2019 - 2024. All rights reserved.