Python:避免if条件?

Python:避免if条件?,python,variable-assignment,conditional-statements,Python,Variable Assignment,Conditional Statements,哪个更好? if not var: var = get_var() 更好的是你更喜欢的。如果,我会使用第一个版本,但这是非常个人化的。第二个版本更像pythonic,我通常使用它。第一个版本对我来说更直观。但话说回来,这都是你自己的口味。两者都没有错 对于阅读代码的人来说,前者更容易理解 问问自己,当你在思考你要解决的问题时,脑海中出现的概念是否更接近“如果这个,那么那个”或“两个几乎但不完全是布尔变量的逻辑or”。对我来说,第一个习惯用法,使用显式if的习惯用法,更可取,因为它更显式

哪个更好?
if not var:
    var = get_var()

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

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

第一个版本对我来说更直观。但话说回来,这都是你自己的口味。

两者都没有错

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


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

对我来说,第一个习惯用法,使用显式if的习惯用法,更可取,因为它更显式

然而,我看到or构造被引用为首选/更具python风格的构造

因此,一方面,
显式优于隐式(禅宗引文),另一方面,简短的表达可以被视为pythonic(尽管在所有情况下,shorter并不等同于pythonic!)


一个密切相关的SO问题是,if和or习语都列在这里

如果or是一个短路运算符(如果left hand为true,则不会计算right hand参数),则两者最终将编译为相同的代码


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

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

希望这有帮助。

-tjw

当两种风格的变化在风格上如此接近时,我使用
timeit
作为打破僵局的工具:更快一定意味着更接近Python的主流,即更好。嘿,这总比没完没了的辩论好,y?-)所以:


如果
if
有它——当
var
为false时等价,当
为true时更快实际上,如果您试图确定之前是否使用调用获取var设置了var,那么我认为这两种形式都是错误的。Python将许多非常普通的值视为计算为布尔值“false”:0、None、[]、(、)、set()和{}。假设var是一个整数,get_var()恰好返回0。现在,不管使用哪种形式,get_var()都会被一次又一次地调用,即使我们已经知道var是0

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

  • 查看globals()或locals()返回的dict

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

  • 使用类似None的sentinel值,并将var初始化为该值;然后,如果var为None,则可以测试
    :var=get_var()
    (使用“is”,而不是“=”)。如果您运气不好,并且从get_var()返回的潜在值中没有一个,那么您需要定义自己的特殊尚未定义的值,使用类似
    not_defined=object()
    ,用它初始化var,然后如果var未定义,您可以测试


这是否意味着
if
构造不是Pythonic?什么构成了“Pythonic”?在我看来,如果
var
恰好是布尔值,那么它更像Pythonic。否则,可能不会,虽然上下文可能会改变我的想法。还考虑:<代码> var=var,如果var var GETvar()/代码>——在这种情况下不一定是推荐,只是另一个选项。如果GETYVAR()返回0,该怎么办?您将继续调用它,即使您已经知道该值。它应该是get_new_var()。这根本不会“避免”if条件。你在问什么?如果你每次都想要一个新的var,为什么不直接编写代码
var=get\u new\u var()
?当没有其他问题时,进行微优化@Chris,我认为这更像是“找出Python主流是什么”——Python核心开发人员(包括我在内)最终花更多的时间优化频繁且受欢迎的使用,而不是被边缘化和嘲笑,因此
timeit
是一种获取他们(我们的)总体价值的方法为一个其他方面没有实际意义的决定所做的努力。对我来说似乎有点自相矛盾,那么他们是如何实施短循环的呢?@Alex-我的评论比它读到的更像是在开玩笑。原谅我的业余网络讽刺技巧。@Chris,当然,只是想澄清我的理由@Johannes,
x=x
不会被Python编译器优化,因为Python编译器实际上是一个超级简单的编译器,因此短路导致的结果相当于
var=var
并不会使后者“免费”!-)
var = var if var else get_var()
$ 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