高效确认python中的数组或者元组为空
在python中,为了确认一个数组或者元组是不是为空,可以使用三种方法,(由于数组和元组在这里判断类似,因此统一以数组说明。)分别是与空数组比较,查看数组长度是否为零和直接if判断。
python实现方法如下
#! env python
## 判断数组为空的3种方法
###方法1:与空数组比较
def compare_empty(a):
if a == []:
return True
return False
###方法2:判断数组长度是否为0
def compare_len(a):
if len(a) == 0 :
return True
return False
###方法3:if直接判断
def list_if(a):
if a:
return False
return True
一般情况下,我们推荐使用的方法是第三种方法,因为这是python内置的方法,运行起来会比较高效,那么为什么呢,python内部是如何实现的呢?
三种方法在python内部的实现原理
由于python是解释性语言,代码运行时首先会被转化为字节码,然后再由解释器来真实运行。为了确认python内部的实现过程,这里需要使用python里的dis包的dis方法查看代码生成的字节码。以下为3种不同方法的字节码查看。
与空数组比较
#! env python
import dis
def compare_empty(a):
if a == []:
return True
return False
dis.dis(compare_empty)
"""
In [7]: dis.dis(compare_empty)
2 0 LOAD_FAST 0 (a)
2 BUILD_LIST 0
4 COMPARE_OP 2 (==)
6 POP_JUMP_IF_FALSE 12
3 8 LOAD_CONST 1 (True)
10 RETURN_VALUE
4 >> 12 LOAD_CONST 2 (False)
14 RETURN_VALUE
"""
如果没有使用过dis的话看起来可能会比较麻烦,这里稍微解释下,左边的数字代表原始代码的行数,右边的代表改行被翻译成的字节码,一般来说一行python代码会对应多行字节码。由于不同的方法的差别仅仅是在第二行if判断语句,因此只看第二行翻译的字节码差异即可。
在该方法中,有4个步骤:
"""
2 0 LOAD_FAST 0 (a)
2 BUILD_LIST 0
4 COMPARE_OP 2 (==)
6 POP_JUMP_IF_FALSE 12
"""
分别为:
- LOAD_FAST 查找内存中的变量a并将其置于栈的顶部
- BUILD_LIST 新建一个长度为0的数组并放在栈顶
- COMPARE_OP 迭代取出两个栈的数据,查看是否相同,并将结果存放在栈顶
- POP_JUMP_IF_FALSE 将栈顶的数据取出得到布尔值
在三种方法中,这是最慢的,因为需要重新开辟内存空间并通过迭代的方式比较,造成后续还需要进行垃圾清理并且速度慢。
查看长度是否为0
def compare_len(a):
if len(a) == 0 :
return True
return False
dis.dis(compare_len)
"""
2 0 LOAD_GLOBAL 0 (len)
2 LOAD_FAST 0 (a)
4 CALL_FUNCTION 1
6 LOAD_CONST 1 (0)
8 COMPARE_OP 2 (==)
10 POP_JUMP_IF_FALSE 16
"""
该方法中,判断数组长度是否为0,一共需要6个步骤:
- LOAD_GLOBAL 查看len函数的定义并置于栈顶
- LOAD_FAST 查找变量a并置于栈顶
- CALL_FUNCTION 取出a并将其传递到栈顶运算得到结果并放置于栈顶
- LOAD_CONST 将常量0置于栈顶
- COMPARE_OP 这一步与上面方法相同
- POP_JUMP_IF_FALSE 也相同
此方法使用了内置的len函数,并且没有迭代过程,相对来说速度更快一点。
内置if判断数组布尔值
def list_if(a):
if a:
return False
return True
dis.dis(list_if)
"""
2 0 LOAD_FAST 0 (a)
2 POP_JUMP_IF_FALSE 8
"""
此方法只有两个步骤
- LOAD_FAST 与前面一样,内存中查找a并放置于栈顶
- POP_JUMP_IF_FALSE 同上,查看栈顶数据并跳转
该方法使用的两个步骤在前面的方法中均用到,因此是最快的一个方法。 那么为什么可以直接通过POP_JUMP_IF_FALSE判断呢,这是因为python其实是由c语言编写的,它会查看c语言中变量的属性如果长度大于0那么就是true否则返回false,所以使用cpython编写python代码也可以加快程序运行速度。
总结
本文通过3种方法确认一个数组或者元组是否为空,并通过dis模块查看不同运行方法中的字节码了解程序运行中的具体运行机制。
- 原文作者:春江暮客
- 原文链接:https://www.bobobk.com/814.html
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。