Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python if len(x)和if x之间的差异_Python_List - Fatal编程技术网

Python if len(x)和if x之间的差异

Python if len(x)和if x之间的差异,python,list,Python,List,我有以下清单 x = [1,2,3] if x: dosomething() if len(x)>0: dosomething() 在上面的示例中,哪个if语句工作得更快?内部 if x: 将获取列表对象的大小,并检查它是否为非零值 在这种情况下, if len(x) > 0: 你正在明确地做这件事 而且 对于序列(字符串、列表、元组),使用空序列为false这一事实 是:如果不是,则如下: 如果如下所示: 否:如果len(seq) 如果不是len(序号) 第一条

我有以下清单

x = [1,2,3]

if x:
 dosomething()

if len(x)>0:
  dosomething()
在上面的示例中,哪个if语句工作得更快?

内部

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

在这种情况下,

if len(x) > 0:
你正在明确地做这件事


而且

对于序列(字符串、列表、元组),使用空序列为false这一事实

<代码>是:如果不是,则如下: 如果如下所示: 否:如果len(seq) 如果不是len(序号)
第一条语句的运行速度更快,因为它不需要执行函数,而在第二条语句中,在它运行之前需要执行一些操作,在这种情况下,
len(x)
如果
x
list
,则(从结果来看)没有区别。但第一个要快一点:

%%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

在几乎所有情况下,如果x,则应将第一个与
一起使用。只有当您想区分
None
False
和空的
列表(或类似的东西)时,您可能需要其他东西。

在@thefourtheye的答案上展开,下面是一个演示/证明,当您检查列表的真值时,会调用
\len\uu

>>> 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所建议的那样。

如果您查看每个方法的步骤,您会发现第二个方法执行的步骤几乎是第一个方法的两倍

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\u FAST
POP\u JUMP\u IF\u FALSE
JUMP\u FORWARD
LOAD\u CONST
,以及
返回值
。但第二种方法还需要做额外的工作
LOAD\u GLOBAL
CALL\u FUNCTION
LOAD\u CONST
,以及
COMPARE\u OP
。因此,第一种方法会更快


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

你为什么不自己计时呢?从标准库中学习,你就再也不用问“哪个更快”的问题了。有了上面提供的代码,只需在
中删除
if
语句:)Typo:missing
就可以更快了
否:if len(seq)
@PM2Ring我刚刚意识到PEP-8本身就有这个错误