[python學習手冊-筆記]003.數值類型

003.數值類型

本系列文章是我我的學習《python學習手冊(第五版)》的學習筆記,其中大部份內容爲該書的總結和我的理解,小部份內容爲相關知識點的擴展。python

非商業用途轉載請註明做者和出處;商業用途請聯繫本人(gaoyang1019@hotmail.com)獲取許可。web

這不是演習!數據庫

好了,從本章開始,咱們就要正式進入python的學習.所涉及的內容深度會有所提高,可是還到不了學習完1+1=2以後就開始微積分推導的陡峭程度. 相關的補充內容我會以知識點補充或者外鏈的方式添加進來.express

數值類型的基本知識

Python中的數值類型主要包括如下三類:數組

  • **整數:**也就是咱們所熟悉的int類型. 在python3之中,再也不區分整數和長整數.也就是說容許整數具有無限的精度. 固然,這個精度取決於咱們計算機的內存大小.
  • 浮點數: 浮點數在標準的CPython中,採用的是C語言的雙精度浮點數. 其精度和構建python解釋器的C語言編譯器的雙精度一致.具體的精度信息能夠在 sys.float_info中查看,以下圖,詳細解釋請參考文檔
  • 複數: 複數由實部和虛部構成,字面量的寫法能夠寫成 a+bj的形式或者直接經過 complex(real,imag)來構建
In [2]: import sys
# 雙精度浮點數相關信息
In [3]: sys.float_info
Out[3]: sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)
# 虛數的表示
In [4]: cmplx = complex(1,2)

In [5]: cmplx
Out[5]: (1+2j)

In [6]: type(cmplx)
Out[6]: complex

除了以上三種類型以外,python的數字類型還包括布爾類型.網絡

字面量 相關的解釋
1234,-24,0 整數類型,無大小限制
1.23,3.1415 浮點數類型
0o177,0x9ff,0b10011100 python3中的十六進制,八進制和十進制
3+4j,3.0+4.0J 複數
set("spam"),{1,2,3,4} 集合
Decimal('1.0'),Fraction(1,3) 小數和分數(有理數)
bool(X),True,False 布爾類型

各類進制的表示

python的整數默認採用十進制進行表示. 一樣,也支持二進制,八進制,十六進制的表示.編輯器

  • **二進制:**0b或者0B開頭表示
  • **八進制:**0o或者0O開頭表示(注意第二個字符是字母o)
  • **十六進制:**0x或者0X開頭表示

可使用內置函數bin(I),oct(I),hex(I)來進行進制轉換. 同時也支持int(str,base)將字符串轉換爲對應的十進制整數.函數

In [12]: a =11

In [13]: hex(a)
Out[13]: '0xb'

In [14]: oct(a)
Out[14]: '0o13'

In [15]: bin(a)
Out[15]: '0b1011'

# 將10按二進制轉換爲十進制
In [18]: int('10',base=2)
Out[18]: 2
# 將16進制ff轉換爲十進制
In [19]: int('ff',base=16)
Out[19]: 255

python的運算符

運算符 描述
yield x 生成器函數send協議
lambda args:expression 匿名函數
x if y else z 三元表達式
x or y 邏輯或
x and y 邏輯與
not x 邏輯非
x in y, x not in y 成員關係,用於可迭代對象和集合
x is y,x is not y 對象同一性測試
x<y,x<=y,x>y,x>=y 大小比較,集合的超集和子集
x==y,x!=y 值的等價運算
x|y 按位或,集合的並集
x^y 按位異或,集合的對稱差集
x&y 按位與,集合的交集
x<<y,x>>y 將x左移y位,將x右移y位
x+y 加法,拼接
x-y 減法,集合的差集
x*y 乘法,重複
x%y 求餘數,格式化
x/y 真除法
x//y 向上去整
-x,+x 取負,取正
~x 按位取非
x**y 冪運算
x[i] 索引
x[i:j:k] 分片
x(...) 函數,方法,類,其餘可調用對象的調用
x.attr 屬性索引
(...) 元組,表達式,生成器表達式
[....] 列表,列表推導表達式
{....} 字典,集合,集合與字典的推導

上表中基本把python中的運算符表達式所有列舉出來了. 並且是按照運算優先級從低到高的順序列舉出來的.工具

對於混合類型的運算,永遠向着精度更高的方向進行.固然也能夠經過內置函數來進行強制類型轉換性能

In [4]: 40+3.14
Out[4]: 43.14

In [5]: int(3.14)
Out[5]: 3

In [6]: float(5)
Out[6]: 5.0

python的數值比較

數值的比較會輸出一個布爾值,好比:

In [10]: 1<2
Out[10]: True

In [11]: 2.0>3
Out[11]: False

In [13]: 2.0!=2.0
Out[13]: False

看第三項能夠知道,python是支持混合類型的數值比較的.如前面所說,python在進行混合類型的數值運算的時候,會先將其轉換爲精度更高的類型,而後再進行計算.

所謂鏈式比較以下例所示:

In [16]: 1<2<3
Out[16]: True

In [17]: 1==2<3
Out[17]: False

其中第一個等效於1<2 and 2<3,第二個等效於1==2 and 2<3

數值的比較是基於數值大小進行的,對於整型的比較是沒問題的,可是對於浮點數的比較,就可能出現不可預知的錯誤. 好比如下的例子:

In [14]: 1.1+2.2 == 3.3
Out[14]: False

In [15]: 1.1+2.2
Out[15]: 3.3000000000000003

這個例子就有點讓人匪夷所思了,1.1+2.2憑什麼不等於3.3...

這是因爲浮點數是有限的比特位數,致使沒法精確的表示某些數值.這個問題不只在python中存在,在其餘語言中一樣存在. 不過python有分數和小數,能夠很好的規避這些問題. 畢竟python適合科學計算的特性不是白來的.

python中的除法

python中有三種風格的除法和兩種除法運算符.

X/Y

這個是所謂的經典除法和真除法.在python2中,對於整數而言,會省略小數的部分,對於浮點數則會保留小數部分. 在python3中,不管整數仍是浮點數,真除法都會保留小數部分.

In [18]: 4/2
Out[18]: 2.0

In [19]: 10/3
Out[19]: 3.3333333333333335

X//Y

向下取整除法,注意這個叫法,叫向下取整,也就是比真正結果小的那個最接近的整數.

In [20]: 10//4
Out[20]: 2

In [21]: 10//3
Out[21]: 3

向下取整除法(floor division)和截斷除法的區別:

//操做符嚴格來講應該叫作向下取整除法,其獲取的結果是真正結果之下的最接近的整數.這個對於正數來講比較好理解,捨棄小數的部分.對於負數而言,就是比其結果小的最接近的負數.

In [25]: 10//4,10//-4
Out[25]: (2-3)

In [26]: 10//9,10//-9
Out[26]: (1-2)

經過這兩個例子就能夠很好的看出來了.

那麼python中的截斷,能夠經過math模塊中的trunc方法實現

In [28]: import math

In [29]: math.floor(2.5)
Out[29]: 2

In [30]: math.floor(-2.5)
Out[30]: -3

In [31]: math.trunc(2.5)
Out[31]: 2

In [32]: math.trunc(-2.5)
Out[32]: -2

那對於所謂的截斷除法,咱們可使用一種特殊的方式.

In [33]: 5//-2
Out[33]: -3

In [34]: math.trunc(5/-2)
Out[34]: -2

按位操做

按位操做在處理網絡數據包,串行程序等二進制數據的時候十分方便,因此python中如C語言同樣,也支持位移操做.

In [1]: x=1
# 左移兩位
In [2]: x<<2
Out[2]: 4
# 按位或
In [3]: x|2
Out[3]: 3
# 按位與
In [4]: x&1
Out[4]: 1
# 按位異或
In [5]: x ^ 1
Out[5]: 0

其餘的就很少說了,不難. 用到時候查下文檔就完事兒了.

其餘內置數值工具

數值處理相關的方法除了pow,abs這些內置方法以外,大部分的方法都在內置模塊math之中. 這裏舉一些例子:

In [6]: import math

In [7]: math.pi
Out[7]: 3.141592653589793

In [8]: math.e
Out[8]: 2.718281828459045

In [9]: math.sin(90)
Out[9]: 0.8939966636005579

In [10]: math.sqrt(144)
Out[10]: 12.0

In [11]: pow(2,4)
Out[11]: 16

In [12]: abs(-42.1)
Out[12]: 42.1

In [13]: min(3,2,1)
Out[13]: 1

In [14]: max(1,3,4,9)
Out[14]: 9
# 四捨五入
In [15]: round(3.123),round(2,512),round(-3.123),round(-2.512)
Out[15]: (32-3-3)

其餘數值類型

複數

說實話,複數是個啥我都快忘了...可是python支持這玩意兒. 複數主要能夠用在工程計算和科學計算中,固然做爲一個數學學渣,愛莫能助. 因此這一塊很少說了. 簡單說一下複數的表達形式.

python中的複數是由兩個浮點數組成,分別表示複數的實部和虛部.能夠寫成 X+Yj的形式. 複數相關的處理方法主要集中在cmath模塊中.

用到的時候再說吧,估計也用不到...

小數

python2.4以後引入了小數這種數據類型,正式名稱叫作Decimal. 須要注意的是python中的Decimal類型和浮點數不是一個東西. 小數很像浮點數,可是小數有固定的位數和小數點.好比,咱們可使用小數對象實現一個只有兩位小數位精度的浮點數.

根據以前的介紹咱們已經瞭解了浮點數中一個詭異的現象,好比:

In [16]: 0.1+0.1+0.1-0.3
Out[16]: 5.551115123125783e-17

前文說過,這是因爲浮點數存儲位數有限形成的.那麼python做爲科學計算領域的老大,這麼不嚴謹的事情,確定是不容許發生的.因此python中定義了一中新的數據類型Decimal來解決這個問題.

In [18]: Decimal('0.1')+Decimal('0.1')+Decimal('0.1')-Decimal('0.3')
Out[18]: Decimal('0.0')

這裏須要注意一點的是,上面咱們是從字符串建立的小數對象.若是咱們直接從浮點數建立小數對象呢?

In [19]: Decimal(0.1)+Decimal(0.1)+Decimal(0.1)-Decimal(0.3)
Out[19]: Decimal('2.775557561565156540423631668E-17')

完了,饒了一圈又回來了...

這是python處理的問題.直接從浮點數建立小數對象的話,這個轉換是精確的,也就說浮點數會按照其存儲的內容完完整整的被建立爲小數.(感受這一篇寫完了是否是能夠寫一篇浮點數相關的文章...)

咱們能夠經過設置小數數值精度,舍入模式等方法來解決這個問題.(回頭用到的時候再寫吧,我如今也有點懵逼...)

分數

分數類型在python中稱之爲Fraction,實現了一個有理數對象.實質上就是顯式的保持一個分子和一個分母,從而避免浮點數的精度問題. 分數的實現不像浮點數同樣依靠底層硬件,因此,分數在性能上比浮點數要弱.

In [2]: from fractions import Fraction
# 1/3
In [3]: x=Fraction(1,3)

In [4]: y=Fraction(4,6)

In [5]: x
Out[5]: Fraction(13)

In [6]: y
Out[6]: Fraction(23)

In [7]: print(y)
2/3

In [8]: x+y
Out[8]: Fraction(11)

集合

集合,就是數學上的那個集合.按照集合的定義,一個元素在集合中不管添加多少次,在集合中也都會表示爲1次,也就說集合不能有重複的元素(初中數學好像是這麼教的...) 因此集合這個類型在涉及數值和數據庫的操做中是有着普遍應用的.

集合有着列表和字典的一些共同特性,好比集合是可迭代的對象,能夠按需增加或者縮短,能夠包含多種數據類型. 另外,集合中須要注意的,集合的元素是無序的.

集合的建立比較簡單:

In [9]: x=set('abcde')

In [10]: y=set('abcfg')

In [11]: x
Out[11]: {'a''b''c''d''e'}

In [12]: y
Out[12]: {'a''b''c''f''g'}

集合支持數學上集合的那些操做:

# 差集
In [13]: x-y
Out[13]: {'d''e'}
# 並集
In [14]: x|y
Out[14]: {'a''b''c''d''e''f''g'}
# 交集
In [15]: x&y
Out[15]: {'a''b''c'}
# 異或(這個叫什麼集啊...沒學過呢...)
In [16]: x^y
Out[16]: {'d''e''f''g'}
# x是否爲y的超集,y是否爲x的超集
In [17]: x>y,x<y
Out[17]: (FalseFalse)

集合也支持成員測試:

In [19]: 'a' in x
Out[19]: True

集合的修改:

In [20]: x.add('w')

In [21]: x
Out[21]: {'a''b''c''d''e''w'}
# 求並集
In [24]: x.update(set('awq'))

In [25]: x
Out[25]: {'a''b''c''d''e''q''w'}

In [26]: x.remove('q')

In [27]: x
Out[27]: {'a''b''c''d''e''w'}

集合做爲一個可迭代對象,也支持len()方法和for循環以及列表表達式:

In [29]: for item in set('abc'):print(item*3)
bbb
ccc
aaa

集合的另一種建立方法

# 能夠直接使用{}來建立集合
In [30]: x={1,2,3,4}

In [31]: x
Out[31]: {1234}

In [32]: type(x)
Out[32]: set

這裏須要注意的是,對於{}空的內容python依舊會認爲其是一個字典,因此要建立空的集合仍是要使用set()方法

In [34]: type({})
Out[34]: dict

做爲一種可迭代對象,集合也支持推導表達式:

In [35]: {x for x in 'spam'}
Out[35]: {'a''m''p''s'}

最後須要注意一點,python的集合有一個限制. 那就是集合中只能包含不可變的(可哈希化的)對象類型. 像列表,字典這樣的玩意兒不能做爲集合的元素.而像字符串,數字常量,元組這樣的類型是能夠做爲集合的元素的.

集合的優點

上文中已經講過,集合中的元素只能出現一次.除了實現集合的數學特性以外. 集合還能夠用來過濾重複性數據,提取列表,字符串以及其餘可迭代類型中的差別,也能夠用來進行一些順序無關的等價性測試.

# 使用集合進行重複項過濾
In [36]: L = [1,2,2,3,4,5,2,1]

In [37]: set(L)
Out[37]: {12345}

In [38]: L=list(set(L))

In [39]: L
Out[39]: [12345]

差別數據的提取

In [40]: set('while')-set('what')
Out[40]: {'e''i''l'}

In [41]: set(dir(bytes))-set(dir(bytearray))
Out[41]: {'__getnewargs__'}

進行順序無關性的兩組數據的等價性測試

In [45]: L1 = [1,2,3,4,5]

In [46]: L2 = [5,4,1,2,3]

In [47]: L1 == L2
Out[47]: False

In [48]: set(L1)==set(L2)
Out[48]: True

布爾類型

python的布爾型的定義和C語言有一點類似,本質上是int類型的子類. 有True和Flase兩個實例.其實就是整數1和0的定製版. 布爾類型提升了python代碼的可讀性. 這讓咱們在設置flag的時候,更加形象. 咱們能夠寫while True而不用寫while 1

In [49]: type(True)
Out[49]: bool

In [50]: True+4
Out[50]: 5

In [51]: True ==1
Out[51]: True

In [52]: True is 1
Out[52]: False

臥槽,這章終於寫完了...就這樣...

相關文章
相關標籤/搜索