【问题标题】:Python: avoiding if condition?Python:避免 if 条件?
【发布时间】:2011-01-26 05:53:43
【问题描述】:

哪个更好?

if not var:
    var = get_var()
(或)

var = var 或 get_var()

另外,我怎么知道两者中的哪一个更好?
编辑:
史蒂夫的另一个选择,

var = var if var else get_var()

【问题讨论】:

  • 还要考虑:var = var if var else getvar () - 在这种情况下不一定是推荐,只是另一种选择。
  • 如果 get_var() 返回 0 怎么办?即使你已经知道它的价值,你也会继续调用它。
  • 应该是 get_new_var()..
  • 这根本不会“避免”一个 if 条件。你在问什么?
  • 如果你每次都想要一个新的变量,为什么不直接编码var = get_new_var()

标签: python variable-assignment conditional-statements


【解决方案1】:

实际上,如果您尝试确定 var 之前是否已通过调用 get_var 设置,那么我认为两种形式都是错误的。 Python 将许多完全普通的值视为布尔值“false”:0、None、[]、(,)、set() 和 {}。因此,假设 var 将是一个整数,而 get_var() 恰好返回 0。现在,无论您使用哪种形式,get_var() 都会一次又一次地被调用,即使我们已经知道 var 是 0!

有几种方法可以检测变量是否已定义:

  • 查看由 globals() 或 locals() 返回的字典

  • 将语句 var = var 包装在 try/except 块中,捕获 NameError

  • 使用类似 None 的标记值,并将 var 初始化为该值;然后你可以测试if var is None: var = get_var()(使用'is',而不是'==')。如果你运气不好,并且 None 是从 get_var() 返回的潜在值,那么你需要定义你自己的特殊尚未定义的值,使用类似 NOT_DEFINED = object() 的东西,用它初始化 var,然后你可以测试if var is NOT_DEFINED

【讨论】:

    【解决方案2】:

    对我来说,第一个习语,即使用显式 if 的习语更可取,因为更显式。

    但是,我看到 or 构造被引用为首选/更 Pythonic 的构造。

    所以,一方面,Explicit is better than implicit(Zen 引文),另一方面,short 表达式可以被视为 pythonic(尽管在所有情况下,short 并不等同于 pythonic!)

    一个密切相关的 SO 问题是most idiomatic way to convert None to empty string,其中列出了 if 和 the or 成语。

    【讨论】:

      【解决方案3】:

      当两种风格的变体在风格上如此接近时,我使用timeit 作为决胜局:更快必须意味着更接近 Python 的主流,即更好。嘿,这比无休止的辩论要好,是吗?-) 所以:

      $ python -mtimeit -s'var=0; getvar=lambda:0' 'var = var or getvar()'
      1000000 loops, best of 3: 0.359 usec per loop
      $ python -mtimeit -s'var=0; getvar=lambda:0' 'if not var: var = getvar()'
      1000000 loops, best of 3: 0.361 usec per loop
      $ python -mtimeit -s'var=1; getvar=lambda:1' 'var = var or getvar()'
      10000000 loops, best of 3: 0.123 usec per loop
      $ python -mtimeit -s'var=1; getvar=lambda:1' 'if not var: var = getvar()'
      10000000 loops, best of 3: 0.0899 usec per loop
      

      if 有它——当var 为假时等效,当它为true 时更快。

      【讨论】:

      • 什么都不重要,微优化!
      • @Chris,我把它更多地看作是“找出 Python 的主流是什么”——Python 核心开发人员(包括我在内)最终会花费更多的时间来优化经常和赞赏的使用,而不是边缘并嗤之以鼻,所以timeit 是一种捕捉他们(我们)努力的总体总和的方式,以做出其他没有实际意义的决定。
      • 对我来说似乎有点矛盾,那他们又是如何实现短路的呢?
      • @Alex - 我的评论本意是比它读到的更半开玩笑。原谅我业余的网络讽刺技巧。
      • @Chris,当然,只是想澄清我的推理。 @Johannes,x=x 不会被 Python 编译器优化掉,Python 编译器实际上是一个超级简单的编译器,因此短路导致相当于 var=var 的事实并没有使后者“免费” !-)
      【解决方案4】:

      解释器可能会同时执行它们。在代码可读性方面存在权衡。哪个语句更容易识别它的作用?当然,第一个要清楚得多。对我来说,阅读这篇文章,我不得不更多地考虑第二个。由于可读性提高,我会使用第一个,即使第二个语句稍微“性感”。

      希望这会有所帮助。
      -tjw

      【讨论】:

        【解决方案5】:

        考虑到 or 是一个短路运算符,两者最终都会编译成相同的代码(如果左手为真,它不会计算右手参数)。

        我更喜欢第一个,因为它更清楚地表达了您的意图。第二个可能更紧凑。

        【讨论】:

          【解决方案6】:

          都没有错。

          对于阅读代码的人来说,前者更容易理解。

          问问自己,当您考虑要解决的问题时,脑海中浮现的概念是否更接近“如果这个,那么那个”或“两个几乎但不完全是布尔值的逻辑或变量。”

          【讨论】:

            【解决方案7】:

            第一个版本对我来说更直观。但话又说回来,这完全取决于您自己的口味。

            【讨论】:

              【解决方案8】:

              第二个更pythonic,我通常使用它。

              【讨论】:

              • 这是否意味着 if 构造不是 Pythonic?什么是“Pythonic”?
              • IMO 它更像 Pythonic if var 恰好是布尔值。否则,可能不会,尽管上下文可能会改变我的想法。
              【解决方案9】:

              更好的是你更喜欢的那个。我会使用if 的第一个版本,但这是非常个人化的。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-04-27
                • 1970-01-01
                • 2014-07-08
                • 2018-04-11
                • 2011-02-01
                • 2019-03-27
                • 1970-01-01
                • 2017-03-02
                相关资源
                最近更新 更多