Python比较操作,if和None

时间:2014-01-09 13:30:54

标签: python operators

我正在阅读一些代码,我注意到这段代码有很多这样的代码:

 try: 
   rv = somefunction()
 except SomeException, e:
   rv = 0

 if rv == 0:
    doSomething() ...

在我看来,使用这种比较操作的方式必然要慢于:

try: 
   rv = somefunction()
 except SomeException, e:
   rv = None

 if is not None:
    doSomething() 
    ...

3 个答案:

答案 0 :(得分:2)

这样做会更有效率:

 try: 
     rv = somefunction()
 except SomeException, e:
     doSomething() ...

如果其他地方需要整数值,您可能仍需要设置rv = 0,这是上述示例的限制因素。

答案 1 :(得分:1)

也许这取决于你是在python 2还是python 3.在python 2中,唯一的'慢'操作是`== None'。我认为这是因为低范围内的整数是预先创建的对象,但实际上这并不重要。

In [53]: x = 0

In [54]: %timeit x is 0
10000000 loops, best of 3: 38 ns per loop

In [55]: %timeit x == 0
10000000 loops, best of 3: 36.5 ns per loop

In [56]: x = 1

In [57]: %timeit x is 0
10000000 loops, best of 3: 37.3 ns per loop

In [58]: %timeit x == 0
10000000 loops, best of 3: 36.5 ns per loop

In [59]: %timeit x is None
10000000 loops, best of 3: 38.1 ns per loop

In [60]: %timeit x == None
10000000 loops, best of 3: 82.9 ns per loop

现在,在前3个案例中,x是一个int,它与前三个案例中的类型相同,而不是最后一个。所以尝试了一个额外的东西,使x成为一个字符串,所以它不匹配0:

的类型
In [62]: x = 'x'

In [63]: %timeit x is 0
10000000 loops, best of 3: 38.7 ns per loop

In [64]: %timeit x == 0
10000000 loops, best of 3: 92.5 ns per loop

In [65]: %timeit x is None
10000000 loops, best of 3: 39.1 ns per loop

In [66]: %timeit x == None
10000000 loops, best of 3: 77.1 ns per loop

在这种情况下,无论类型是什么,'is'仍然非常快,而混合类型相等检查更慢。这是有道理的,因为'is'只是对id的等式检查,而equals可以任意慢。

意思是如果你真的关心这个(你可能不需要如上所述,除非这是在内循环中),你应该创建一个sentinel对象(任何时候),然后使用{ {1}}运算符直接检查它。 is是一个方便的,只要它不是有效值; None0可以履行相同的职责。但它不一定是那些。

答案 2 :(得分:0)

为了展示我的配偶,这可能是真的,我使用None, 0False做了一些基准测试:

我在这个问题之前已经阅读了When is the `==` operator not equivalent to the `is` operator? (Python)。我甚至添加了一些基准测试来试图说服我的伙伴们这可以优化:

In [92]: def TestInt():
   ....:     i = 0
   ....:     if i:
   ....:         pass
   ....:     

In [93]: def TestBool():
   ....:     i = False
   ....:     if i:
   ....:         pass
   ....:     

In [95]: def TestNone():
   ....:     i = None
   ....:     if i:
   ....:         pass
   ....:     


In [97]: timeit.timeit(TestInt, number=10**5)
Out[97]: 0.01352691650390625

In [98]: timeit.timeit(TestBool, number=10**5)
Out[98]: 0.014671087265014648

In [99]: timeit.timeit(TestNone, number=10**5)
Out[99]: 0.009851932525634766

显然比较对象是否None总是更快一点!