繁体   English   中英

Python 列表理解中的多个 if/elif 语句

[英]Multiple if/elif statements in a Python list comprehension

所以我是 Python 的新手,一个需要一些习惯的概念是列表理解。 我已经读到,如果使用正确,它们可以提高计算速度,并且如果您要以正确的方式学习 Python,它们是非常了解的。

我正在编写一个实现粒子聚合算法的程序,该算法涉及将多达 10^6 个粒子累积到一个不断增长的集群中。 我将回顾我的代码以尽可能优化性能,并且我有以下 function:

 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 

这个 function 使每个粒子(或我在代码中称之为步行者)在随机方向上采取单位长度的步长,并防止粒子离开 N x N 网格。 我注意到我正在创建并返回一个新列表updated_positions ,并且由于此列表和输入walker列表可能非常大,我对列表推导的了解告诉我这可能是使用它的好时机。 然而,在这个问题的其他一些帖子中,只有一个 if/else 需要评估,人们回答说只使用一个好的 ole 时尚 for 循环。

那我有几个问题:

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

2) 把这个 for 循环写成列表理解有意义吗? 这样做有什么好处吗?

我提出这个问题的主要目的是建立更多的直觉,了解何时适合列表理解,以及看看这个 function 是否可以用一个来提高效率。

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

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

不应该使用列表推导的情况是逻辑过于复杂。

For 循环更简单,因为它们允许:

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

然而,正如 Sayse 所建议的,我们通常可以使用额外的数据结构和辅助函数来简化逻辑,以允许列表理解。

没有 if/else 语句的列表理解(需要绕过逻辑)

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]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM