【问题标题】:Are one-line 'if'/'for'-statements good Python style?单行“if”/“for”语句是好的 Python 风格吗?
【发布时间】:2010-12-16 06:54:41
【问题描述】:

在这里,我经常看到某人的代码以及看起来像“单行”的代码,这是一条以传统“if”语句或“for”循环工作的标准方式执行的单行语句。

我在 Google 上四处搜索,并没有真正找到您可以执行哪些类型的操作?任何人都可以建议并最好给出一些例子吗?

例如,我可以在一行中做到这一点吗:

example = "example"
if "exam" in example:
    print "yes!"

或者:

for a in someList:
    list.append(splitColon.split(a))

【问题讨论】:

  • 不确定您在寻找什么...您能再解释一下吗?
  • 现在 Python 不是有那些奇怪的 lambda 东西可以让你在一行中添加更多内容吗?当然,并不是说我会使用它们。我更喜欢旧的做事方式:-)
  • 我还没有研究过 lambda。每次我在这里的问题中看到这个词时,我都会快速点击书签!
  • 我认为她/他指的是列表推导。
  • @DominicBou-Samra:起初我还认为 OP 是在询问列表推导,但仔细检查后,它们只意味着 “单行 if 语句或 for 语句”我>

标签: python for-loop if-statement idioms


【解决方案1】:

嗯,

if "exam" in "example": print "yes!"

这是一种改进吗? 。您甚至可以在if-clause 的主体中添加更多语句,方法是用分号分隔它们。不过,我建议反对

【讨论】:

  • 除了codegolf,当然,分号很重要:-)
  • Anurag:Stephan 在这段代码中使用“示例”这个词可能是有原因的。
  • @_bravado:正确。我认为您可以省略“公正”这个词:可读性是编程的重要准则。在大多数语言中,将多个语句放在一行上是不受欢迎的,但在 Python 中更是如此。它被认为是非pythonic,至少部分是因为它不符合重要空白的决定所基于的哲学。
  • 即使只是“某人”阅读您的代码……也适用于您自己!如果您在很短的时间内没有看过自己的代码,您会惊讶地发现阅读自己的代码是多么困难。
  • @Vladius:代码 sn-p 可以,是的。答案作为一个整体建议反对这种风格,正是因为 PEP-8。 (五年多以前,或许应该更清楚地说明这一点。)
【解决方案2】:

我发现在大多数情况下,在一行中使用块子句是个坏主意。

再次笼统地说,它会降低代码形式的质量。高质量的代码形式是python的一个关键语言特性。

在某些情况下,python 会提供一种在一行上做事的方法,这些方法肯定更 Python 化。诸如 Nick D 在列表理解中提到的内容:

newlist = [splitColon.split(a) for a in someList]

尽管除非您特别需要可重用列表,否则您可能需要考虑改用生成器

listgen = (splitColon.split(a) for a in someList)

请注意,两者之间最大的区别是您不能在生成器上重复,但使用起来更高效。

在现代版本的 python 中还有一个内置的三元运算符,可以让你做类似的事情

string_to_print = "yes!" if "exam" in "example" else ""
print string_to_print

iterator = max_value if iterator > max_value else iterator

有些人可能会发现这些比类似的if (condition): 块更具可读性和可用性。

归根结底,它与代码风格以及您所在团队的标准有关。这是最重要的,但总的来说,我建议不要使用一行代码,因为 python 中的代码形式非常重要。

【讨论】:

  • 我发现三元运算符对logging.info("Found %d %s", num_results, "result" if num_results == 1 else "results") 等情况很有用。
  • 其实我很喜欢python的三元。一旦你习惯了它,它就会比大多数语言更具可读性。它使具有历史意义的 <condition> ? <true value> : <false value> 看起来很古老。
  • 谢谢,这真的很有帮助!
【解决方案3】:

更一般地说,以下所有在语法上都是有效的:

if condition:
    do_something()


if condition: do_something()

if condition:
    do_something()
    do_something_else()

if condition: do_something(); do_something_else()

...等等。

【讨论】:

  • 最后是分号..我一直在寻找!
  • 为了清楚起见,请不要真的像这样使用分号!我只是想完整地回答这个问题。
  • 有什么理由吗? tha's 简化了我的一些 if 语句,然后是 print 语句,然后是 sys.exit()
  • 它使您的代码无法被除您之外的任何人阅读。它只是不时尚或惯用的 Python。
  • 为了搭载@CoryPetosky 的评论,PEP8 也不推荐这样做。如果您不想深入阅读实际指南,只需在包含 if condition: do_stuff(to, args) 之类的代码上运行任何 pep8 linter。 Pylama 在 PEP8 下将其标记为错误,甚至没有警告。
【解决方案4】:

不只是删除换行符的语言功能示例,尽管仍然不相信这比更冗长的版本更清晰

a = 1 如果 x > 15 否则 2

【讨论】:

    【解决方案5】:
    for a in someList:
        list.append(splitColon.split(a))
    

    你可以将上面的内容改写为:

    newlist = [splitColon.split(a) for a in someList]
    

    【讨论】:

    • 第一次使用list,第二次使用newlist。有什么改变的理由吗?
    • @Cawas,哦,确实。 OP 在他的代码中使用了“列表”。 shadow 内置函数或类型名称(即“列表”)不是一个好习惯。这就是我在回答中使用“newlist”的原因。
    【解决方案6】:

    如果只有一行,Python 允许您将缩进子句放在同一行:

    if "exam" in example: print "yes!"
    
    def squared(x): return x * x
    
    class MyException(Exception): pass
    

    【讨论】:

    • 示例未定义。它需要引号。
    • 示例的哪一部分你不明白?每个代码片段都不需要声明它的所有变量。
    【解决方案7】:

    您可以通过省略example 变量在一行中完成所有这些操作:

    if "exam" in "example": print "yes!"
    

    【讨论】:

      【解决方案8】:

      旧版本的 Python 只允许在 for ...: if ...: 或类似的块介绍性语句之后使用单个简单语句。

      我看到一个人可以在同一行有多个简单的语句作为这些语句中的任何一个。但是,有多种组合不起作用。例如我们可以:

      for i in range(3): print "Here's i:"; print i
      

      ...但是,另一方面,我们不能:

      for i in range(3): if i % 2: print "That's odd!"
      

      我们可以:

      x=10
      while x > 0: print x; x-=1
      

      ...但我们不能:

      x=10; while x > 0: print x; x-=1
      

      ...等等。

      无论如何,所有这些都被认为是非常非pythonic。如果您编写这样的代码,那么有经验的 Pythonistas 可能会对您的技能持暗淡的看法。

      在某些情况下,将多个语句组合在一行中是可以接受的。例如:

      x=0; y=1
      

      ...甚至:

      if some_condition(): break
      

      ...对于简单的break continue 甚至return 语句或分配。

      特别是如果需要使用一系列elif,可能会使用类似:

      if     keystroke == 'q':   break
      elif   keystroke == 'c':   action='continue'
      elif   keystroke == 'd':   action='delete'
      # ...
      else:                      action='ask again'
      

      ...那么您可能不会太讨厌您的同事。 (然而,elif 的链就像尖叫声被重构为一个调度表......一个可能看起来更像的字典:

      dispatch = {
          'q': foo.break,
          'c': foo.continue,
          'd': foo.delete
          }
      
      
      # ...
      while True:
          key = SomeGetKey()
          dispatch.get(key, foo.try_again)()
      

      【讨论】:

        【解决方案9】:

        Dive into python 有一点他谈到了他所谓的and-or trick,这似乎是一种将复杂逻辑塞进一行的有效方法。

        基本上,它模拟了 c 中的三元运算符,为您提供了一种测试真假并基于此返回值的方法。例如:

        >>> (1 and ["firstvalue"] or ["secondvalue"])[0]
        "firstvalue"
        >>> (0 and ["firstvalue"] or ["secondvalue"])[0]
        "secondvalue"
        

        【讨论】:

        • 小心:这 not 模拟了 C 的三元运算符。 1 ? 0 : 2 等于 0,但 1 and 0 or 2 等于 2。使用专门为此目的制作的另一个构造要安全得多:0 if 1 else 2产生0)。
        • (这里的问题是0 计算结果为False。您的代码确实 工作的原因是因为"firstvalue" 计算结果为True。)
        • 这个技巧早于三元运算符,并且充其量只是一个近似值,因为它的布尔值为 False 的值存在问题。
        • 我包含的链接涵盖了这一点,并提供了一种解决方法。我选择了更简单的版本,但鉴于响应,看来我应该采取安全的方式来做到这一点。
        【解决方案10】:

        这是一个带有动作的“if else”示例。

        >>> def fun(num):
            print 'This is %d' % num
        >>> fun(10) if 10 > 0 else fun(2)
        this is 10
        OR
        >>> fun(10) if 10 < 0 else 1
        1
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多