如果len(x)和x之间的区别

时间:2016-02-22 12:15:57

标签: python list

我有以下清单

x = [1,2,3]

if x:
 dosomething()

if len(x)>0:
  dosomething()

在上面的例子中if语句会更快地运行吗?

5 个答案:

答案 0 :(得分:2)

如果 xlist,则(从结果中)没有差异。但第一个更快一点:

%%timeit
if x:
    pass
10000000 loops, best of 3: 95 ns per loop

比第二个:

%%timeit
if len(x) > 0:
    pass
1000000 loops, best of 3: 276 ns per loop

在几乎所有情况下,您都应该使用if x的第一个。只有当您想要区分NoneFalse和空list(或类似的东西)时,您才可能需要其他内容。

答案 1 :(得分:1)

内部,

if x:

将获取列表对象的大小,并检查它是否为非零值。

在这种情况下,

if len(x) > 0:

你明确地这样做了。

此外,PEP-0008 suggests the first form

  

对于序列,(字符串,列表,元组),请使用空序列为假的事实。

     
Yes: if not seq:
     if seq:

No: if len(seq)
    if not len(seq)

答案 2 :(得分:1)

第一个语句可以更快地工作,因为它不需要执行一个函数,而在第二个语句中需要执行一些事情才能运行,在这种情况下len(x)

答案 3 :(得分:1)

通过@thefourtheye扩展答案,这里是一个演示/证明,当您检查列表的真值时,__len__被调用:

>>> class mylist(list):
...     def __len__(self):
...         print('__len__ called')
...         return super(mylist, self).__len__()
... 
>>> a = mylist([1, 2, 3])
>>> if a:
...     print('doing something')
... 
__len__ called
doing something
>>> 
>>> if len(a) > 0:
...     print('doing something')
... 
__len__ called
doing something
>>> 
>>> bool(a)
__len__ called
True

这是一个快速的时机:

In [3]: a = [1,2,3]
In [4]: timeit if a: pass
10000000 loops, best of 3: 28.2 ns per loop
In [5]: timeit if len(a) > 0: pass
10000000 loops, best of 3: 62.2 ns per loop

因此,隐式检查稍微快一点(可能是因为全局len函数没有开销),并且正如PEP-0008所提到的那样。

答案 4 :(得分:1)

如果您查看每个方法的dis.dis(),您会发现第二个方法的步数几乎是第一个方法的两倍。

In [1]: import dis

In [2]: def f(x):
   ....:     if x: pass
   ....:     

In [3]: def g(x):
   ....:     if len(x) > 0: pass
   ....:     

In [4]: dis.dis(f)
  2           0 LOAD_FAST                0 (x)
              3 POP_JUMP_IF_FALSE        9
              6 JUMP_FORWARD             0 (to 9)
        >>    9 LOAD_CONST               0 (None)
             12 RETURN_VALUE        

In [5]: dis.dis(g)
  2           0 LOAD_GLOBAL              0 (len)
              3 LOAD_FAST                0 (x)
              6 CALL_FUNCTION            1
              9 LOAD_CONST               1 (0)
             12 COMPARE_OP               4 (>)
             15 POP_JUMP_IF_FALSE       21
             18 JUMP_FORWARD             0 (to 21)
        >>   21 LOAD_CONST               0 (None)
             24 RETURN_VALUE

他们都需要LOAD_FASTPOP_JUMP_IF_FALSEJUMP_FORWARDLOAD_CONSTRETURN_VALUE。但第二种方法需要另外做 LOAD_GLOBALCALL_FUNCTIONLOAD_CONSTCOMPARE_OP。因此,第一种方法会更快。

然而,实际上,两种方法之间的时间差异将非常小,除非这些if语句在代码中运行数百万次,否则不会显着影响程序的性能。这听起来像是我过早优化的一个例子。