在Python中压缩`x if x else y`语句

Posted

技术标签:

【中文标题】在Python中压缩`x if x else y`语句【英文标题】:Compressing `x if x else y` statement in Python 【发布时间】:2012-12-15 20:14:18 【问题描述】:

我非常熟悉 Python 的三元运算符方法:

value = foo if something else bar

我的问题很简单:如果没有事先分配,是否可以从返回操作数之一(... ifelse ...)引用在 (if ...) 中评估的术语?

这里的动机是有时我在if ... 中使用表达式,这正是我希望在三元运算中得到的结果;虽然发生这种情况,对于小的表达式,重复它没有问题,但是对于更长的表达式,它会变得有些讨厌。以此为例:

value = info.findNext("b") if info.findNext("b") else "Oompa Loompa"

【问题讨论】:

好吧,Oompa Loompa 很有趣! @AspiringAqib 我们没有任务,但我们仍然可以享受一些oompa loompas (: 嗯,你有解决办法吧? @AspiringAqib 是的,我想这已经足够了,甚至可能是最好的解决方案(:最好继续KISS'in things(: 为什么findNext 不采用可选的默认值,例如get 以及以它为原型的数百种其他方法?那么你根本不需要这个。 【参考方案1】:

没有办法做到这一点,这是故意的。三元 if 只应该用于琐碎的情况。

如果你想使用两次计算的结果,把它放在一个临时变量中:

value = info.findNext("b")
value = value if value else "Oompa Loompa"

一旦你这样做了,很明显你在做一些愚蠢的事情,实际上写这个的pythonic方式是:

value = info.findNext("b")
if not value:
    value = "Oompa Loompa"

这实际上比您最初的尝试少了 5 次击键。

如果你真的想要节省击键,你可以这样做:

value = info.findNext("b") or "Oompa Loompa"

但许多风格指南和 BDFL 都不鼓励这样做。

如果您只执行一次,最好更加明确。如果你这样做了六次,那么让findNext 采用可选的默认返回而不是None,就像所有那些内置函数和stdlib 函数一样简单且更好:

def findNext(self, needle, defvalue=None):
    # same code as before, but instead of return None or falling off the end,
    # just return defvalue.

那么你可以这样做:

value = info.findNext("b", "Oompa Loompa")

【讨论】:

我实际上对编程有一些奇怪的抽搐:我不喜欢写超过 70 列,我真的很欣赏单行解决方案;这里的问题是关于紧凑性而不是明确的单词数量。不过,我接受您的回答,因为您正在回答我的二进制问题yes/no。尽管如此,同意使用 or,正如@Ignacio 所指出的那样,毕竟是最好的解决方案。 返回None 与返回null 相同,因此返回just as bad。 @Rubens:编写 1 行解决方案的 Pythonic 方法是将任何复杂的内容封装在显式函数中。如果您可以将defval 添加到findNext,请执行此操作;如果不能,请编写一个包装器。不同的语言有不同的惯用风格(例如,在 Haskell 中,命名一个你只会调用一次的函数是代码异味),并且不同的语言更强烈地遵循它们的惯用语(例如,在 perl 中,“只有一种方法可以做它”将被视为错误,而不是功能)。但如果你选择了 Python,你应该学习惯用的 Python。 @Tinctorius:None 出现在示例中,因为我认为这是 OP 的原始 findNext 返回的内容,就像 dict.get 和同一模型上的所有其他方法一样。它显然返回 something falsey,并且没有 real 结果可以是falsey,或者 OP 的代码是错误的,我假设它不是。无论如何,这与OP的问题无关。 (但是,作为旁注:您认为 Haskell 的 Nothing 是否违反了 void 安全性?如果不是,除了静态与动态类型之外,NothingNone 之间有什么区别?) @abarnert:如果您有动态类型,那么我非常喜欢“默认返回值”方法。抛出KeyError 也很好,但人们可能会发现这会使代码混乱。我认为 Haskell 的 Maybe 根本没有违反 void 安全性。默认情况下,无效的不安全语言使许多类型可以为空。 Maybe 允许您选择可空性。 Haskell 无效不安全的唯一方法是它的底部值(即难以捕捉的终止,如undefined,或非终止,如fix id),但要解决这个问题,你的语言会变得更难使用 并且更难实施。【参考方案2】:

根本不要使用if ... else。相反,请利用 Python 的合并运算符。

value = info.findNext("b") or "Oompa Loompa"

【讨论】:

它是certainly a shortcut,@Rubens。 x or y 应该编译成与if bool(x) then x else y 相同的代码。 bool 打电话给.__nonzero__() 可以这样做,但这并不意味着你应该。如果您这样做的次数足够多以至于节省 5 次击键很重要,请修改 findNext 方法以采用默认值。否则,明确写出来。 如果混入了任何falsy的东西,这种事情会烧死你。考虑[] or 'default' - 这可能是您正在寻找的,也可能不是。

以上是关于在Python中压缩`x if x else y`语句的主要内容,如果未能解决你的问题,请参考以下文章

small= x if x<y else y python的这句语法怎么解释?

Webpack中压缩代码文件

Webpack中压缩代码文件

在python中压缩文件

linux 如何用 unzip解压一个压缩包中的一个文件? tar可以

在 python 中压缩文件时如何保留目录?