【问题标题】:Shorter, more pythonic way of writing an if statement编写 if 语句的更短、更 Pythonic 的方式
【发布时间】:2010-11-22 02:19:59
【问题描述】:

我有这个

bc = 'off'

if c.page == 'blog':
    bc = 'on'

print(bc)

有没有更 Pythonic(和/或更短)的方式在 Python 中编写?

【问题讨论】:

  • 使用'on'和'off'吗?是否可以仅用布尔值来表示此信息,我的意思是 bc = (c.page == 'blog') 要好得多。

标签: python if-statement


【解决方案1】:

最短的应该是:

bc = 'on' if c.page=='blog' else 'off'

通常这可能看起来有点混乱,所以你应该只在清楚它的含义时才使用它。不要将它用于大的布尔子句,因为它开始看起来很快就很难看。

【讨论】:

    【解决方案2】:

    这是:

    1. 肯定更短
    2. 可以说是 Pythonic(Python 2.5 之前的版本,引入了有争议的 X if Z else Y 语法)
    3. 可读性有问题。考虑到这些警告,这里是:

      bc = ("off","on")[c.page=="blog"]
      

    编辑:根据要求,通用形式为:

       result = (on_false, on_true)[condition]
    

    解释:condition 可以是任何计算结果为布尔值的东西。然后将其视为整数,因为它用于索引元组:False == 0True == 1,然后从元组中选择正确的项目。

    【讨论】:

    • 令人着迷。和上面的另一个一样,你能概括一下并解释一下吗? (如......你不是在开玩笑#3)。
    • ("off", "on") 是一个元组,c.page=="blog" 计算为正在访问的元素的索引
    • 本来想投反对票的,因为实在是太丑了,后来才想起来是自己用的。
    • 这是我在 2.5 不可用时使用的;我发现“和...或”是不可接受的,因为它读起来很奇怪,如果和值不是真的,它就会失败。 '(a, b)[cond]' 的缺点是 a 和 b 都被评估,所以你不能依赖快捷方式,这意味着你不能转换像“'nothing'”这样的结构,如果 item 是 None else项目名称”。
    • 我喜欢它,但与 X if Z else Y 相比,if Z 是假的,我们只评估 Y 而不是 X,所以它会失败,例如如果键不在字典中:adict[ k ] if adict.__contains( k ) else k
    【解决方案3】:

    好吧,我不是一个 Python 人,请对此持保留态度,但多年来我已经编写(并且,更困难的是,阅读)许多聪明的代码,我发现我自己现在对可读代码有强烈的偏好。即使我是一个 Python 人,我也知道你的原始代码在做什么。可以肯定的是,您可以将其隐藏起来,也许会给一两个 Python 专家留下深刻印象,但为什么呢?

    【讨论】:

    • C 人使用 i++。 Pythonic if 可以用作明显条件的简写,因为 i++ 或 i+= 可以用作明显操作的简写。
    • @freiksenet:我认为更好的比较是使用其他语言中的 ?: 语句,简而言之,简单——内联——条件。而且,可以说,这些可以使代码更具可读性,而不是用没有添加任何功能的额外行将其弄乱。
    • 仅供参考,“Pythonic”是一个强调可读性而非简洁性的术语。
    • 然而,一般来说,较短的代码更具可读性。您可以做得过火,但在其他条件相同的情况下,我希望代码中的标记更少。特别是,如果带有副作用主体的语句很难推理,因为它很难略读:如果不阅读整个内容,您将无法知道它们所触及的内容。 C 的三元或内联 iffreiksenet 提到没有这些问题:它需要一些时间来适应,但它是一种比原始分支更易于维护的样式。
    • 我认为新的条件表达式可读性很好。但是,我完全同意必须为可读性而写作。
    【解决方案4】:

    您可以使用内联 if 语句:

    >>> cpage = 'blog'
    >>> bc = 'on' if cpage == 'blog' else 'off'
    >>> bc
    'on'
    >>> cpage = 'asdf'
    >>> bc = 'on' if cpage == 'blog' else 'off'
    >>> bc
    'off'
    

    this blog 上有一些关于该功能的文章,相关的 PEP 是 PEP308。内联 if 语句是在 Python 2.5 中引入的。

    这个不太pythonic,但你可以用这种方式使用and/or

    >>> cpage = 'asdf'
    >>> bc = (cpage == 'blog') and 'on' or 'off'
    >>> bc
    'off'
    >>> cpage = 'blog'
    >>> bc = (cpage == 'blog') and 'on' or 'off'
    >>> bc
    'on'
    

    这个在 lambda 语句中比单独在一行中更常用,但形式

     A and B or C
    

    类似于

       if A:
           return B
       else:
           return C
    

    此方法(如 PEP 308 mentions)的主要警告是,当 B 为 false 时,它​​会返回 C

    【讨论】:

    • 第二个看起来真的令人困惑。您能否扩展答案以解释它为什么会这样工作?
    • 感谢您的解释。它对我来说仍然很不可读。我认为第一个选项更好。
    • 第二个选项是在我们得到第一个选项之前人们使用的,在那些情况下,在一行中塞满东西比可读性更重要..
    • 第二个肯定在可读性方面得分较低。不是 Pythonic。
    • 在 PEP308 之前,and/or 方法 用于 是在 lambda 中执行条件的 Pythonic 方式。请参阅 PEP 的前两段:python.org/dev/peps/pep-0308
    【解决方案5】:

    如果您可以在访问它们的函数之外计算值(即值是静态的,这也解决了 scrible 的答案 cmets 中的评估问题),则另一种可能性是使用 dict。

    want_bc = {True: "on", False: "off"}
    # ...
    bc = want_bc[c.page == "blog"]
    

    我更喜欢这个和/或在优先计算而不是测试的一般规则下的元组索引解决方案。

    【讨论】:

      【解决方案6】:

      你可以使用,

      a = b if c else d 
      

      但如果你使用的是 2.5 之前的 python 版本,

      bc = c.page == "blog" and "on" or "off"
      

      也可以做到这一点。

      【讨论】:

        猜你喜欢
        • 2015-03-06
        • 2012-11-26
        • 1970-01-01
        • 2023-02-17
        • 2022-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-01
        相关资源
        最近更新 更多