【问题标题】:Nested for loops in python in a single line在单行中嵌套python中的for循环
【发布时间】:2015-03-05 12:54:25
【问题描述】:

这里有一些代码,我正在努力使其更具可读性。它可以工作,但是嵌套的 for 循环和 try/if 使乍一看有点难以理解发生了什么。

有人可以就如何加入嵌套的 for 循环或压缩此代码给我一些建议吗?

matcher = None
if re.match(_RE_OBJECT, nodes.replace(LQMN, '')):
  matcher = alias
else:    
  for x in lister[0].conditions:
    for y in x.codes:
      try:
        if y.id.split(',')[1] == condition:
          matcher = x.codenames
      except IndexError:
        pass

【问题讨论】:

  • 如果您将 for 循环压缩在一行中,我认为您不会使您的代码“更具可读性”。您是否希望获得更短的代码或更易读的代码? (坦率地说,这段代码并不是那么难以阅读或过度嵌套......)
  • 理想情况下尝试获得更具可读性的代码。
  • 您的 for 循环和 try:... except 块很好。但是你可以在你的_RE_OBJECT 上使用re.compile()。 (如果您缩进 4 个空格而不是 2 个空格,那么您的代码看起来会更令人愉悦。恕我直言)。如果你的目标是可读性,那么试着想出比xy 更有意义的名字。简短的、一次性的名称在单循环中是可以的,但在深度嵌套的代码中它们开始变得有点迟钝。
  • 然后放置嵌套的 for 循环不会对您的事业有多大帮助。我认为这很容易阅读,即使我不知道lister 是什么,我也知道发生了什么。此外,我要做的唯一改变是更深的缩进。 (但这也可能是在 SO 上而不是在实际代码中格式化,afaik python 缩进是 4 个空格)。
  • @ljetibo:Python 不在乎你的缩进单元有多大,只要你的缩进与你的缩进匹配。您可以使用单个空格缩进 - 我经常在交互式解释器中使用,但它在脚本中看起来真的很难看,因为它很难跟踪正在发生的事情。

标签: python for-loop nested


【解决方案1】:

您可以使用生成器表达式嵌套循环并添加过滤器,使 IndexError 处理程序过时:

candidates = ((x, y) for x in lister[0].conditions for y in x.codes if ',' in y.id)
for x, y in candidates:
    if y.id.split(',')[1] == condition:
        matcher = x.codenames

在此处使用除xy 之外的更有意义的名称会进一步提高可读性:

candidates = ((cond, code) for cond in lister[0].conditions for code in cond.codes
              if ',' in code.id)
for cond, code in candidates:
    if code.id.split(',')[1] == condition:
        matcher = cond.codenames

【讨论】:

  • 让我知道答案。然而,由于 genexp 本质上是 backwards 这并不一定更 可读 ...
  • 这似乎是一个聪明的解决方案,但 python 告诉我生成器表达式在第一个 'for' 处的语法无效。我不知道您实际上可以在一行中列出一个接一个。
  • @nerdinary:抱歉,已更正;左侧表达式需要使用括号来消除元组与 genexp 语法本身的歧义。我的错。
【解决方案2】:

您可以使用单行 if 和 continue 语句代替 try 语句:

some_var = y.id.split(',')
if len(some_var) < 2: continue
if some_var[1] == condition:
    matcher = x.codenames

并将 some_var 替换为有意义的名称。

【讨论】:

  • Python 中的异常处理非常高效,因此正确的try:... except block 通常比等效的基于if 的代码更快。
  • 它总是取决于你正在处理的项目,如果速度不是那么重要,或者代码运行得足够快,你可能想使用if,但如果速度是更重要的是你会使用try:... except
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-09
  • 2013-06-05
  • 2019-04-15
  • 2013-08-09
  • 2021-06-28
  • 2020-06-08
相关资源
最近更新 更多