自引用三元组

时间:2013-08-13 01:43:02

标签: python idioms ternary

我已经这样做了一段时间了:

x = x if x else y

在x可能是NoneFalse0''[]{}的各种情境中。< / p>

我知道纯粹主义者宁愿我:

if not x:
    x = y

但忘记了,那不是我的问题。 我的问题是:

x = x if x else y除了它是三元的事实之外还有什么“错误”吗?具体来说,可以像这样进行三元自我分配。

注意

我的qustion x = x if C else y好的。我知道是。

非常感谢

4 个答案:

答案 0 :(得分:1)

没有,没有错 事实上,这是非常pythonic。我记得读过那个(通过Guido本人)三元等同的首选。我会看看我是否可以挖掘参考文献 就个人而言,我发现另一种方式更具可读性,但你没有要求我的个人意见。 ;)

更新: 这是引用。 核心Python编程,第2版; Wesley J. Hun; Prentice Hall 2007

  

如果您来自C / C ++或Java世界,那么很难   忽略或克服Python没有条件或者有条件的事实   三元算子(C?X:Y)的时间最长。 [...] Guido有   由于他的信仰,他拒绝为Python添加这样的功能   保持代码简单,不给程序员简单的混淆方法   他们的代码。然而,经过十多年,他已经屈服了,   主要是因为人们尝试过的容易出错的方式   使用和和 - 或 - 多次错误地模拟它。根据   FAQ,正确的一种方法是(C和[X]或[Y])[0]。该   唯一的问题是社区无法就语法达成一致。   (你真的要看看PEP 308才能看到所有不同的东西   提案。)这是人们拥有的Python领域之一   表达了强烈的感情最后的决定归结为Guido   选择所有选择中最受欢迎(和他最喜欢的),   然后将其应用于标准库中的各个模块。根据   对于PEP,“这篇评论近似于实际使用的一个样本   案例,跨越各种应用程序,由多个人编写   具有不同背景的程序员。“这就是语法   最终选择集成到Python 2.5:X,如果C else Y。

答案 1 :(得分:1)

从语言设计的角度来看,没有错。正如另一张海报所提到的,它甚至是首选方式。我甚至会问你为什么暗示三元组是错的?

从可读性/可维护性的角度来看,事情的数据有点多了。一方面,如果你将拥有大量的休闲,非Python读者/维护者,这个结构(而不​​是if not x: x= C)的可读性要低得多。另一方面,您的程序很可能包含许多其他(并且更深入)的Pythonism。您有权期望“读者”获得最少的知识。

从性能的角度来看,x作为变量,两种形式都可以通过不同的实现在同一代码中进行优化(如果没有得到有效优化)。这些术语没有区别。

更新:

我不知道Guido对@Edward引用的主题的看法。我很高兴他同意我的看法。或者我和他在一起。但是他对引入三元运算符是绝对正确的,因为它比x= (x,C)[not x]x= x or C更加清晰,后者已被许多具有C背景的早期Python程序员使用(和推广)(和也许还是一个“酷”,差异化的东西)。顺便说一下,两者通常都是正确的(取决于预期的确切语义)。

答案 2 :(得分:1)

x = x if c else y使用ternary没有任何问题,但是,在x = x if x else y的情况下,逻辑确实只是简化为

x = x or y

这是因为在Python x or y评估为'if x is false, then y, else x'

所以x if x else y == y if not x else x == x or y

显然,x or y是最清晰的,应该使用。

答案 3 :(得分:1)

我犹豫不决,因为这是我真正的意见:

不要微观优化。用你感觉舒服的;使用什么使您的代码最具可读性。如果这是你认为最具可读性的话,那么三元语句就完全可以了。

那就是说,

ben@nixbox:~$ python3 -m timeit 'x = 1; x=x if x else 2'
10000000 loops, best of 3: 0.0345 usec per loop
ben@nixbox:~$ python3 -m timeit '''
> x=1
> if not x:
>     x=2
> '''
10000000 loops, best of 3: 0.0239 usec per loop

将x重新分配给自身会有一些小的开销。

dis.dis(f)
  2           0 LOAD_FAST                0 (x) 
              3 POP_JUMP_IF_FALSE       12 
              6 LOAD_FAST                0 (x) #this is the extra instruction
              9 JUMP_FORWARD             3 (to 15) 
        >>   12 LOAD_CONST               1 (1) 
        >>   15 STORE_FAST               0 (x) 
             18 LOAD_CONST               0 (None) 
             21 RETURN_VALUE

回到我的要点:不要担心。用你喜欢的东西。