一、布尔(bool)数据类型讲解
1.概念讲解
bool数据类型只有两个值,分别是True和False,注意大小写是严格要求的,不能写成true和false。
在现实世界中,真,正确,对,正,这组词汇表示了一种肯定的意思,与之相对应的则是假,错误,错,反,表示一种否定的意思。在python语言中,True就等同于真,正确,对,正,是肯定, False等同于假,错误,错,反,是否定。bool类型的值通常用于if语句中,程序根据条件表达式的真假决定走哪个逻辑分支。
#最简单的例子是通过数值比较,可以得出True或False的判断
>>> 4 > 3
True
>>> 4 > 6
False
>>> type(4 > 3)
<class 'bool'>
>>> type(True)
<class 'bool'>
#通过type函数可以查看到,比较表达式的结果是True或False,True和False这两个值的类型是bool。
Python3中布尔(bool)类型是整数(int)类型的子类型:布尔类型可以当做整数来对待,即 True 相当于整数值 1,False 相当于整数值 0。布尔类型属于整数类型,可以直接用于数值运算。(在 Python2 中是没有布尔型的,它用数字 0 表示 False,用 1 表示 True,上古的事情,这里不再演示)
>>> issubclass(bool, int)
True
#issubclass函数用于判断一个类型对象(第一个参数)是否是另一个类型对象(第二个参数)的子类或实例,这里返回True,证明了bool类型是int类型的子类。
>>> True==1
True
>>> False==0
True
>>> True+1
2
>>> False+1
1
print(True == 1) #True
print(1 == True) #True
print(True is 1) #False
print(1 is True) #False
is和==都可以对两个对象进行比较,而且它们的返回值都是布尔类型。但是它们比较的内容是不同的,不然两个函数的作用就重复了。
python中对象包含三种基本要素:id(返回的是对象的地址)、type(返回的是对象的数据类型)及value(对象的值)。
is和==比较的对象的内容是不同的,即:is比较的是两个对象的地址值,也就是说两个对象是否为同一个实例对象;而==比较的是对象的值是否相等,其调用了对象的__eq__()方法。继续延伸的话,就要讲到赋值(=)、浅拷贝(copy())、深拷贝(deepcopy())的区别和关联,暂且打住。
2.类型转换
我们已经学习过int,float, bool 这3个数据类型,他们之间可以互相转换。
>>> int(True)
1
>>> int(False)
0
>>> float(True)
1.0
>>> float(False)
0.0
>>> bool(1)
True
>>> bool(0)
False
#不仅1是True,除整数0和浮点数0以外的数字都是True,python中,任何数据类型,要么是True,要么是False。
3.True/False的各种形式
虽然True代表1,False代表0。但实际上,python中的任何一个数据对象要么是True,要么是False,所以可以直接在布尔测试的表达式中使用,而并非一定要通过大小比较等方式得到布尔值。比如:
if "a":
print('right')
#结果会打印right,因为 "a" 是True
while 3: #3也是True
可以通过bool()函数来测试数据对象、表达式是True还是False。例如:
>>> bool(0)
False
>>> bool(1)
True
>>> bool('a')
True
>>> bool('')
False
那么,到底哪些类型的数据是True(真),哪些类型的数据是False(假)?
-
整数值0、浮点数值0.0等、空字符串都为假
-
None为假
-
空数据对象都是假,比如
""、
[]、
{}、
()`等-
注意,元组的括号和逗号的特殊性:例如
(())
、(None)
、(1)
这些都不是元组,而是单个数据对象,加上逗号才算是元组。所以,使用括号包围但却不是元组的数据,如果它们是假,则返回假,而不是元组看上去不为空就会返回真 -
print(type((None))) #<class 'NoneType'> print(type((None,))) #<class 'tuple'> #元组里只有一个元素时,也要写入一个逗号,因为()既可以表示为元组的定义形式,也可以作为括号表示算数运算时的优先级,只有一个元素且不写逗号时,(xx)会被认为就是xx本身,不是元组
-
以下是各种内置数据类型的一些真、假示例:
True False
----------------------------------
number: 1、1.1 0、0.0
string: 'a' ''
None: None
list: ['a']、[1] []
[0]、['']、[None]
Set/Dict: {'a'} {}
非tuple: ('a')、(1) ('')、(0)、(None)
是tuple: ('a',)、(1,)、('',)、(0,)、(None,)都是True ()为False
看几个示例:
>>> bool(1), bool(0)
(True, False)
>>> bool('a'), bool('')
(True, False)
>>> bool(None)
False
>>> bool(['a']), bool([1]), bool([]), bool(['']), bool([()])
(True, True, False, True, True)
>>> bool({'a'}), bool({}), bool({''})
(True, False, True)
>>> bool(('a')), bool(()), bool(('')), bool((0)), bool(({}))
(True, False, False, False, False)
>>> bool(((),)),bool((None,))
(True, True)
实际上,一个数据对象是真还是假,是根据这个类型的__bool__()
的返回值(为False则为假)以及__len__()
的返回值(为0则为假)来决定的。
4.逻辑运算:and、or、not
用布尔值时,经常牵扯到逻辑运算,python中只支持字符形式的and、or、not逻辑运算,不支持符号类型的&&、||、!
。
- X and Y:X和Y都为真时,返回真
- X or Y:X或Y为真,返回真
- not X:X真假取反,即X为真时,not X为假;X为假时,not X 为真
- not优先级很低,所以
not a == b
等价于not (a == b)
- not优先级很低,所以
需要注意,and和or会短路运算(即只要能确定真假关系,就立即停止运算),并返回运算的结果(不是返回True/False,而是返回表达式的运算结果)。而not运算是返回True/False的。
例如,and的逻辑运算:
>>> 2 and 3, 3 and 2
(3, 2)
>>> [] and {}
[]
>>> 3 and []
[]
上面第一行and测试,因为and左边的都是True,所以必须得评估and右边的值,那么不管and右边是True还是False,都会返回and右边的值,比如第1行and测试和第5行and测试。在第3行and测试中,因为and左边为False,已经直接能确定为False,所以直接短路返回[]
。也就是说,and运算,不管是真还是假,只要能确定真假,就会停止运算,返回表达式结果。
再看or逻辑运算:
>>> 2 or 3,3 or 2
(2, 3)
>>> [] or 3
3
>>> [] or {}
{}
上面第1行or测试,因为or左边已经能直接确定为True,所以直接短路返回or左边的值。第3行和第5行or测试,因为or左边都为False,所以必须测试右边的,所以不管or右边是True还是False,都返回or右边的值。也就是说,or运算,只要为真,就停止运算,如果为假,就继续往右看,如果直到最右边还是假,那就返回最右边的表达式结果。
再次说明,and、or返回的不是True/False的布尔值,而是逻辑表达式的运算结果。但因为python中只要是数据,要么是True,要么是False,所以and/or/not都可以用于真假测试,and/or还可以在布尔测试的基础上进行赋值操作。
例如,如果变量a为False,就赋值为某个值,否则采用a原有的值。
a = a or "xxx" #如果a是True,则a=a 否则a="xxx"
更通用的一种表达式:变量A取X、Y、Z等表达式中的一个。
A = X or Y #如果X是True,则A=X 否则A=Y
A = X or Y or Z
不仅如此,and/or还能实现if中选择值的功能。例如,下面两段表达式是等价的:
A = (( X and Y) or Z)
if X:
A = Y
else:
A = Z
当然,这种用and/or实现逻辑的可读性太差,能用if的当然用if,不要存有什么炫技心理。
5.布尔值用于判断空和非空
经常会遇到要测试数据是否为空的情况。这里的空可能是None、""、[]、{}、()
中的一种,建议不要使用len() == 0
去测试:
if len(x) == 0:
if not len(x) == 0:
而是直接将数据作为真、假值进行判断,数据如果为空,就一定是False:
if x:
if not x:
二、None数据结构类型讲解
1.概念讲解
None为假,它不是表示对象为空,也不是表示对象未定义。它自身就是一个实实在在的数据对象,在内存中有自己的内存地址,而且整个python全局只有一个唯一的None对象。可以认为,None是一种特殊的数据对象,像数值1、字符串’a’一样,只不过内存中这个数据对象里面存储的数据是我们不得而知的,但它永远表示为False。
>>> a = None
>>> b = None
>>> a is b
True
# None不支持任何运算,也没有内建方法,除了表示空以外,什么都做不了。如果要判断一个对象是否为None,使用is身份运算符
# is比较的是两个对象的地址值,也就是说两个对象是否为同一个实例对象,这里结果为True,印证说明 None是唯一的
2.None的使用技巧
在Python中,没有显式定义return语句的函数、方法,并不意味着没有返回值,它们的默认返回值是None。比如print()函数就没有显式定义return语句,打印该函数的结果,就是None:
>>> a=print("aa")
aa
>>> print(a)
None
有时候,None可以用在技巧里,比如,访问或设置超出列表长度的元素时会报错:
>>> S = []
>>> S[1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> S[1] = 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
为了避免报错,可以预先将某些数量的None对象填充到列表中去,这样列表就具备了元素(尽管它们都是None对象,但访问时不会越界了)。
例如,向列表中填充10个None元素:
>>> S = [None] * 10 #如果想让每个元素也都是列表,实现列表嵌套,需要用 S=[[None]]
>>> S
[None, None, None, None, None, None, None, None, None, None]
>>> S[1]
>>> S[1] = 2
>>> S
[None, 2, None, None, None, None, None, None, None, None]
当然,将None换成其它数据也一样可以,比如0,但用None来填充,一看就知道是为了填充而填充的占位符,不是实际要操作的元素。
另外,预先填充并不能限制列表的长度,可以继续向这个列表中使用列表的append()方法,增加新元素。
三、练习
请直接输出下列代码的执行结果
1. 0 == 0
2. 4 > 4
3. (3 + 4) > 5
记住你的答案并在解释器里验证
>>> 0 == 0
True
>>> 4 > 4
False
>>> (3 + 4) > 5
True
通过这练习题,你新学了两个知识点
- == 判断两个数据是否相等
- 小括号里的内容作为整体看待
- 表达式
两个等号(==) 用于判断两个数据是否相等,如果相等,其结果就是True,反之为False,关于这个运算符,还会在比较运算符教程里讲解,今天只是初步了解。
在数字运算中,小括号的作用和你在小学时所学的一样,表示优先运算,小括号里的内容将被视为一个整体。