python布爾類型和邏輯運算

布爾類型

python中True表示真,False表示假,它們是布爾類型:python

>>> type(True)
<class 'bool'>

在python中,bool的True和False是數值1和0的字符串表示格式,實際上bool類型是int類型的一個子類app

>>> bool.__bases__
(<class 'int'>,)

由於True/False是數值1和0的另外一種表示方式,它們能夠直接參與數值運算。函數

>>> True + 2
3
>>> False + 2 - 1
1

True/False的各類形式

雖然True表明1,False表明0。但實際上,python中的任何一個數據對象要麼是True,要麼是False,因此能夠直接在布爾測試的表達式中使用,而並不是必定要去大小比較、經過函數測試等等。好比:測試

if "a":
while 1:

能夠經過bool()函數來測試數據對象、表達式是True仍是False。例如:code

>>> bool(0)
False
>>> bool(1)
True
>>> bool('a')
True
>>> bool('')
False

那麼,哪些類型的數據是True,哪些類型的數據是False?對象

  • 整數值0、浮點數值0.0等、空字符串都爲假
  • None爲假
  • 空數據對象都是假,好比[]{}()
    • 注意,元組的括號和逗號的特殊性。例如(())(None)(1)這些都不是元組,而是單個數據對象,加上逗號纔算是元組。因此,使用括號包圍但卻不是元組的數據,若是它們是假,則整個返回假,而不是元組看上去不爲空而返回真

如下是各類內置數據類型的一些真、假示例:內存

True                 False
        ----------------------------------
number:   一、1.1               0、0.0
string:   'a'                  ''
None:                          None
list:     ['a']、[1]           []
       [0]、['']、[None]
Set/Dict: {'a'}                {}
tuple:    ('a')、(1)           ()、('')、(0)、(None)

看幾個示例:字符串

>>> 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則爲假)來決定的。string

None

None爲假,它不是表示對象爲空,也不是表示對象未定義。它自身就是一個實實在在的數據對象,在內存中有本身的內存地址,並且整個python全局只有一個惟一的None對象。能夠認爲,None是一種特殊的數據對象,像數值一、字符串'a'同樣,只不過內存中這個數據對象裏面存儲的數據是咱們不得而知的,但它永遠表示爲Falseast

>>> a = None
>>> b = None
>>> a is b
True

在Python中,沒有顯式定義return語句的函數、方法並不意味着沒有返回值,它們的默認返回值是None。好比print()函數:

>>> 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, 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()新元素。

邏輯運算:and、or、not

python中只支持字符形式的and、or、not邏輯運算,不支持符號類型的&&、||、!

  • X and Y:X和Y都爲真時,返回真
  • X or Y:X或Y爲真,返回真
  • not X:X真假取反
    • not優先級很低,因此not a == b等價於not (a == b)

須要注意,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右邊的值,好比第一行and測試,第三行and測試。第二行and測試中,由於and左邊爲False,因此直接能肯定爲False,因此直接短路返回[]

再看or邏輯運算:

>>> 2 or 3,3 or 2
(2, 3)
>>> [] or 3
3
>>> [] or {}
{}

上面第一行or測試,由於or左邊已經能直接肯定爲True,因此直接短路返回or左邊的值。第二行和第三行or測試,由於or左邊都爲False,因此必須測試右邊的,因此無論or右邊是True仍是False,都返回or右邊的值。

再次說明,and、or返回的不是True/False的布爾值,而是邏輯表達式的運算結果。但由於python中只要是數據,要麼是True,要麼是False,因此and/or/not均可以用於真假測試,只不過and/or還能夠在布爾測試的基礎上進行賦值操做。

例如,若是變量a爲False,就賦值爲某個值,不然採用a原有的值。

a = a or "hhhh"

更通用的,變量A取X、Y、Z等表達式中的一個。

A = X or 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。

空、非空測試的建議

常常會遇到要測試數據是否爲空。這裏的空多是None、""、[]、{}、()中的一種,建議不要使用len() == 0去測試:

if len(x) == 0:
if not len(x) == 0:

而是直接將數據做爲真、假值進行判斷:

if x:
if not x:
相關文章
相關標籤/搜索