- Python數據科學零基礎一本通
- 洪錦魁
- 7008字
- 2020-07-03 10:52:19
第3章 Python的基本數據類型
本章摘要
3-1 type( )函數
3-2 數值數據類型
3-3 布爾值數據類型
3-4 字符串數據類型
3-5 字符串與字符
3-6 bytes數據
3-7 專題——地球到月球時間計算/計算坐標軸兩點之間的距離
Python的基本數據類型有下列幾種。
(1)數值數據類型(numeric type):常見的數值數據又可分成整數(int)、浮點數(float)、復數(complex number)(不常用所以不在本書討論范圍)。
(2)布爾值(Boolean)數據類型:也可歸為數值數據類型。
(3)文字序列類型(text sequence type):也就是字符串(string)數據類型。
(4)字符組(bytes,有的書稱字節)數據類型:這是二進制的數據類型,長度是8位。
(5)序列類型(sequence type):list(第6章說明)、tuple(第8章說明)。
(6)對映類型(mapping type):dict(第9章說明)。
(7)集合類型(set type):集合set(第10章說明)、凍結集合frozenset。
3-1 type( )函數
在正式介紹Python的數據類型前,筆者想介紹一下type( )函數,這個函數可以列出變量的數據類型類別。這個函數在讀者未來進入Python實戰時非常重要,因為變量在使用前不需要聲明,同時在程序設計過程中變量的數據類型會改變,我們常常需要使用此函數判斷目前的變量數據類型。或是在進階Python應用中,會調用一些方法(method),這些方法會返回一些數據,可以使用type( )獲得所返回的數據類型。
程序實例ch3_1.py:列出數值變量的數據類型。

執行結果

從上述執行結果可以看到,變量x的內容是10,數據類型是整數(int)。變量y的內容是3.33…3,數據類型是浮點數(float)。下一節會說明為何是這樣。
3-2 數值數據類型
3-2-1 整數int
整數的英文是integer,在計算機程序語言中一般用int表示。如果讀者學過其他計算機語言,在介紹整數時一定會告訴你,該計算機語言使用了多少空間存儲整數,所以設計程序時整數的大小必須是在某一區間, 否則會有溢位(overflow)造成數據不正確。例如,如果存儲整數的空間是32位,則整數大小為-2 147 483 648~2 147 483 647。在Python 2.x版時代,整數被限制在32位,另外還有長整數long,空間大小是64位,所以可以存儲的數值更大,達到-9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807。在Python 3中已經將整數可以存儲空間大小的限制取消了,所以沒有long了,也就是說int可以是任意大小的數值。
英文googol是指自然數10100,計算機是用1e100顯示,這是1938年美國數學家愛德華·卡斯納(Edward Kasner) 9歲的侄子米爾頓·西羅蒂(Milton Sirotta)所創造的。下列是筆者嘗試使用整數int顯示此googol值。

3-2-2 浮點數
浮點數的英文是float,既然整數大小沒有限制,浮點數大小當然也沒有限制。在Python語言中,帶有小數點的數字稱為浮點數。例如:
x = 10.3
表示x是浮點數。
3-2-3 基本數值數據的使用
Python在聲明變量時可以不用設置這個變量的數據類型,未來如果這個變量內容是放整數,這個變量就是整數(int)數據類型,如果這個變量內容是放浮點數,這個變量就是浮點數數據類型。整數與浮點數最大的區別是,整數不含小數點,浮點數含小數點。
程序實例ch3_2.py:測試浮點數。

執行結果

在程序實例ch3_1.py中,x變量的值是“10”,列出x變量是整數變量,在這個實例中,x變量的值是“10.0”,列出x變量是浮點數變量。
3-2-4 整數與浮點數的運算
Python程序設計時不相同的數據類型也可以執行運算,程序設計時常常會發生整數與浮點數之間的數據運算,Python具有簡單的自動轉換能力,在計算時會將整數轉換為浮點數再執行運算。
程序實例ch3_3.py:不同數據類型的運算。

執行結果

上述變量y,由于是整數與浮點數的加法,所以結果是浮點數。此外,某一個變量如果是整數,但是如果最后所存儲的值是浮點數,Python也會將此變量轉成浮點數。
程序實例ch3_4.py:整數轉換成浮點數的應用。

執行結果

原先變量x所存儲的值是整數,所以列出的是整數。后來存儲了浮點數,所以列出的是浮點數。
3-2-5 二進制整數與函數bin( )
可以用二進制方式代表整數,Python中定義凡是以0b開頭的數字,代表這是二進制的整數。
bin( )函數可以將一般整數數字轉換為二進制。
程序實例ch3_5.py:將十進制數值與二進制數值互轉的應用。

執行結果

3-2-6 八進制整數與函數oct( )
可以用八進制方式代表整數,Python中定義凡是以0o開頭的數字,代表這是八進制的整數。
oct( )函數可以將一般數字轉換為八進制。
程序實例ch3_6.py:將十進制數值與八進制數值互轉的應用。

執行結果

3-2-7 十六進制整數與函數hex( )
可以用十六進制方式代表整數,Python中定義凡是以0x開頭的數字,代表這是十六進制的整數。
hex( )函數可以將一般數字轉換為十六進制。
程序實例ch3_7.py:將十進制數值與八進制數值互轉的應用。

執行結果

3-2-8 強制數據類型的轉換
有時候設計程序時,可以自行強制使用下列函數,轉換變量的數據類型。
int( ):將數據類型強制轉換為整數。
float( ):將數據類型強制轉換為浮點數。
程序實例ch3_8.py:將浮點數強制轉換為整數的運算。

執行結果

程序實例ch3_9.py:將整數強制轉換為浮點數的運算。

執行結果

3-2-9 數值運算常用的函數
下列是數值運算時常用的函數。
abs( ):計算絕對值。
pow(x,y):返回x的y次方。
round( ):這是采用運算法則的Bankers Rounding概念,如果處理位數左邊是奇數則使用四舍五入,如果處理位數左邊是偶數則使用五舍六入,例如,round(1.5)=2,round(2.5)=2。
處理小數時,第2個參數代表取到小數第幾位,1代表取到小數第1位。根據保留小數位的后兩位,采用"50"舍去,"51"進位,例如,round(2.15,1)=2.1,round(2.25,1)=2.2,round(2.151,1)=2.2,round(2.251,1)=2.3。
程序實例ch3_10.py:abs( )、pow( )、round( )、round(x,n)函數的應用。

執行結果

需留意的是,使用上述abs( )、pow( )或round( )函數,盡管可以得到運算結果,但是原先變量的值是沒有改變的。
3-2-10 科學記數法
科學記數的概念如下,將一個數字轉換成下列數學式:
a×10n
a是浮點數,例如,123456可以表示為1.23456 ×105,以10為基底數我們用E或e表示,指數部分則轉為一般數字,然后省略“×”符號,最后表達式如下:
1.23456E+5
或
1.23456e+5
如果是碰上小于1的數值,則E或e右邊是負值“-”。例如,0.000123轉成科學記數法,最后表達式如下:
1.23E-4
或
1.23e-4
下列是示范輸出。

4-2-2節和4-2-3節會介紹將一般數值轉成科學記數法輸出的方式,以及格式化輸出方式。
3-3 布爾值數據類型
Python的布爾值(Boolean)數據類型的值有兩種,True(真)或False(偽)。它的數據類型代號是bool。布爾值一般應用在程序流程的控制中,特別是在條件表達式中,程序可以根據這個布爾值判斷應該如何執行下一步工作。
程序實例ch3_11.py:列出布爾值True與布爾值False的數據類型。

執行結果

如果將布爾值數據類型強制轉換成整數,如果原值是True,將得到1;如果原值是False,將得到0。
程序實例ch3_12.py:將布爾值強制轉換為整數,同時列出轉換的結果。

執行結果

在本章一開始說過,有時候也可以將布爾值當作數值數據,因為True會被視為1,False會被視為0,可以參考下列實例。
程序實例ch3_13.py:將布爾值與整數值相加,并觀察最后變量數據類型,可以發現,最后的變量數據類型是整數值。

執行結果

此外,在程序設計中False值不一定是要經過條件判斷是False,才可以得到False,下列情況也會被視為False。
布爾值False 整數0 浮點數0.0 空字符串 '' 空列表 [ ] 空元組 ( ) 空字典 { } 空集合 set( ) None
至于其他的都會被視為True。
3-4 字符串數據類型
字符串(string)數據是指兩個單引號(‘)之間或是兩個雙引號(“)之間任意個數字元符號的數據,它的數據類型代號是str。在英文字符串的使用中常會發生某字中間有單引號的情況,其實這是文字的一部分,如下所示:
This is James's ball
如果用單引號去處理上述字符串將產生錯誤,如下所示:

碰到這種情況,可以用雙引號解決,如下所示:

程序實例ch3_14.py:使用單引號與雙引號設置與輸出字符串數據的應用。

執行結果

3-4-1 字符串的連接
數學的運算符“+”,可以進行兩個字符串相加的操作,產生新的字符串。
程序實例ch3_15.py:字符串連接的應用。

執行結果

3-4-2 處理多于一行的字符串
程序設計時如果字符串長度多于一行,可以使用三個單引號(或是三個雙引號)將字符串括起來即可。
程序實例ch3_16.py:使用三個單引號處理多于一行的字符串。

執行結果

讀者可以留意第2行Silicon左邊的3個單引號和第3行末端的3個單引號,另外,上述第2行若是少了"str1 = ",3個單引號間的跨行字符串就變成了程序的注釋。
3-4-3 轉義字符
在字符串使用中,如果字符串內有一些特殊字符,例如單引號、雙引號等,必須在此特殊字符前加上“\”(反斜杠),才可正常使用,這種含有“\”符號的字符稱為轉義字符(Escape Character)。

字符串使用中特別是碰到字符串含有單引號時,如果是使用單引號定義這個字符串,必須要使用此轉義字符,才可以順利顯示,可參考ch3_17.py的第3行。如果是使用雙引號定義字符串,則可以不必使用轉義字符,可參考ch3_17.py的第6行。
程序實例ch3_17.py:轉義字符的應用,這個程序第9行增加了“\t”字符,所以“can’t”跳到下一個Tab鍵位置輸出。同時有“\n”字符,這是換行符號,所以“loving”跳到下一行輸出。

執行結果

3-4-4 str( )函數
str( )函數有如下幾個用法。
(1)設置空字符串。

(2)設置字符串。

(3)強制將數值數據轉換為字符串數據。

程序實例ch3_18.py:使用str( )函數將數值數據強制轉換為字符串的應用。

執行結果

上述字符串相加,讀者可以想成是字符串連接,執行結果是一個字符串,所以上述執行結果555是數值數據,222333則是一個字符串。
3-4-5 將字符串轉換為整數
int( )函數可以將字符串轉為整數,在未來的程序設計中也常會發生將字符串轉換為整數數據,下面將直接以實例做說明。注:如果數字是非數字字符組成,會產生錯誤。
程序實例ch3_19.py:將字符串數據轉換為整數數據的應用。

執行結果

上述執行結果55是數值數據,2233則是一個字符串。
3-4-6 字符串與整數相乘產生字符串復制效果
在Python中允許將字符串與整數相乘,結果是字符串將重復該整數的次數。
程序實例ch3_20.py:字符串與整數相乘的應用。

執行結果

3-4-7 聰明地使用字符串加法和換行字符\n
有時在設計程序時,想將字符串分行輸出,可以使用字符串加法功能,在加法過程中加上換行字符“\n”即可產生字符串分行輸出的結果。
程序實例ch3_21.py:將數據分行輸出的應用。

執行結果

3-4-8 字符串前加r
在使用Python時,如果在字符串前加上r,可以防止轉義字符被轉義,可參考3-4-3節的轉義字符表,相當于可以取消轉義字符的功能。
程序實例ch3_22.py:字符串前加上r的應用。

執行結果

3-5 字符串與字符
在Python中沒有所謂的字符(character)數據,如果字符串含一個字符,我們稱這是含一個字符的字符串。
3-5-1 ASCII碼
計算器內部最小的存儲單位是位(bit),這個位只能存儲0或1。一個英文字符在計算器中是被存儲成8個位的一連串0或1中,存儲這個英文字符的編碼稱為ASCII(American Standard Code for Information Interchange,美國信息交換標準程序代碼),有關ASCII碼的內容可以參考附錄E。
在這個ASCII表中由于是用8位定義一個字符,所以使用了0~127定義了128個字符,在這128個字符中有33個字符是無法顯示的控制字符,其他則是可以顯示的字符。不過有一些應用程序擴充了功能,讓部分控制字符可以顯示,例如,撲克牌花色、笑臉等。至于其他可顯示字符有一些符號,例如+、-、=、0~9、A~Z或a~z等。這些符號每一個都有一個編碼,我們稱這個編碼是ASCII碼。
可以使用下列函數執行數據的轉換。
chr( x ):返回函數x值的ASCII或Unicode字符。
例如,從ASCII表可知,字符a的ASCII碼值是97,可以使用下列方式打印出此字符。

英文小寫與英文大寫的碼值相差32,可參考下列實例。

3-5-2 Unicode碼
計算機是美國發明的,因此ASCII碼對于英語系國家的確很好用,但是地球是一個多種族的社會,存在幾百種語言與文字,ASCII所能容納的字符是有限的,只要隨便一個不同語系的外來詞,例如,含重音字符就無法顯示了,更何況有幾萬中文字或其他語系文字。為了讓全球語系的用戶可以彼此用計算機溝通,因此有了Unicode碼。
Unicode碼的基本精神是,世上所有的文字都有一個碼值,可以參考下列網頁:
http://www.unicode.org/charts
目前,Unicode內定義了超過11萬的文字,它的定義方式是以“\u”開頭后面有4個十六進制的數字,所以是從“\u0000”至“\uFFFF”。在上述網頁中可以看到不同語系表,其中,East Asian Scripts字段可以看到CJK(Chinese,Japanese,Korean),在這里可以看到漢字的Unicode碼值表,CJK統一漢字的編碼為4E00~9FBB。
在Unicode編碼中,前128個碼值是保留給ASCII碼使用,所以對于原先存在ASCII碼中的英文大小寫、標點符號等,是可以正常在Unicode碼中使用的,Unicode編碼中經常用的是ord( )函數。
ord( x ):可以返回函數字符參數x的Unicode碼值,如果是中文字也可返回Unicode碼值。如果是英文字符,Unicode碼值與ASCII碼值是一樣的。有了這個函數,可以很輕易地獲得字符的Unicode碼值。
程序實例ch3_23.py:這個程序首先會將整數97轉換成英文字符‘a’,然后將字符‘a’轉換成Unicode碼值,最后將中文字‘魁’轉成Unicode碼值。

執行結果

3-5-3 utf-8編碼
utf-8是針對Unicode字符集的可變長度編碼方式,這是Internet目前所遵循的編碼方式,在這種編碼方式下,utf-8使用1~4個byte表示一個字符,這種編碼方式會根據不同的字符變化編碼長度。
ASCII使用utf-8編碼規則
對于ASCII字符而言,基本上它使用1個byte存儲ASCII字符,utf-8的編碼方式是byte的第一個位是0,其他7個位則是此字符的ASCII碼值。
中文字的utf-8編碼規則
對于需要n個byte編碼的Unicode漢字字符而言,例如需要3個byte編碼的漢字,第一個byte的前n(3)位皆設為1,n+1(4)設為0。后面第2和第3個byte的前2位是10,其他沒有說明的二進制全部是此漢字字符的Unicode碼。依照此規則,可以得到漢字的utf-8編碼規則如下:
1110xxxx 10xxxxxx 10xxxxxx # xx就是要填入的Unicode碼
例如,從ch3_23.py的執行結果可知“魁”的Unicode碼值是0x9b41,如果轉成二進制方式則如下所示:
10011011 01000001
我們可以用下列更細的方式,將“魁”的Unicode碼值填入xx內。

從上圖可以得到“魁”的utf-8編碼結果是0xe9ad81,3-6-1節的實例2也可以驗證這個結果。
3-6 bytes數據
使用Python處理一般字符串數據時,可以很放心地使用Unicode字符串str數據類型,至于Python內部如何處理可以不用理會,這些事情Python的直譯程序會處理。
但是有一天需要與外界溝通或交換數據時,特別是我們使用中文,如果不懂中文字符串與bytes數據的轉換,所獲得的數據將會是亂碼。例如,設計電子郵件的接收程序,所接收的可能是bytes數據,這時必須學會將bytes數據轉成Unicode字符串,否則會有亂碼產生。或是有一天你要設計供中國人使用的網絡聊天室,必須設計將使用者所傳送的Unicode中文字符串轉成bytes數據傳上聊天室,然后也要設計將網絡接收的bytes數據轉成Unicode中文字符串,這個聊天室才可以順暢使用。
bytes數據格式是在字符串前加上b,例如,下列是“魁”的bytes數據。
b'\xe9\xad\x81'
如果是英文字符串的bytes數據格式,相對單純地會顯示原始的字符,例如,下列是字符串“abc”的bytes數據。
b'abc'
3-6-1 Unicode字符串轉成bytes數據
將Unicode字符串轉成bytes數據稱為編碼(encode),所使用的是encode( )函數,這個方法的參數是指出編碼的方法,可以參考下列表格。

如果Unicode字符串是英文則轉成bytes數據相對容易,因為對于utf-8格式編碼,Unicode也是用一個byte存儲每個字符串的字符。
實例1:英文Unicode字符串數據轉成bytes數據。
假設有一個字符串string,內容是‘abc’,可以使用下列方法設置,同時檢查此字符串的長度。

下面將Unicode字符串string用utf-8編碼格式轉成bytes數據,然后列出bytes數據的長度、數據類型,以及bytes數據的內容。

實例2:中文Unicode字符串數據轉成bytes數據。
假設有一個字符串name,內容是‘洪錦魁’,可以使用下列方法設置,同時檢查此字符串的長度。

下面將Unicode字符串name用utf-8編碼格式轉成bytes數據,然后列出bytes數據的長度、數據類型,以及bytes數據的內容。

由上述數據可以得到原來Unicode字符串用了3byte存儲一個中文字,所以3個中文字獲得了bytes的數據長度是9。
3-6-2 bytes數據轉成Unicode字符串
對于一個專業的Python程序設計師而言,常常需要從網絡取得數據,所取得的是bytes數據,這時需要將此數據轉成Unicode字符串,將bytes數據轉成Unicode字符串可以稱為譯碼,所使用的是decode( )函數,這個方法的參數是指出編碼的方法,與encode( )函數相同。
實例1:bytes數據轉成Unicode字符串數據。

實例2:bytes數據轉成Unicode字符串數據。
下面是將nameBytes數據使用utf-8編碼格式轉成Unicode字符串的方法,同時列出字符串長度和字符串內容。

3-7 專題——地球到月球時間計算/計算坐標軸兩點之 間的距離
3-7-1 計算地球到月球所需時間
馬赫是音速的單位,主要是為了紀念奧地利科學家恩斯特·馬赫(Ernst Mach)而命名,一馬赫就是一倍音速,它的速度大約是每小時1225千米。
程序實例ch3_24.py:從地球到月球約384 400千米,假設火箭的速度是一馬赫,設計一個程序計算需要多少天、多少小時才可抵達月球。這個程序省略分鐘數。

執行結果

由于尚未介紹完整的格式化程序輸出,所以使用上述方式輸出,第4章會改良上述程序。Python之所以可以成為當今最流行的程序語言,主要是它有豐富的函數庫與方法,上述求商(第5行)和余數(第6行),在2-9節中介紹了divmod( )函數,其實可以用divmod( )函數一次取得商和余數,如下:
商, 余數 = divmod(被除數, 除數) # 函數方法 days, hours = divmod(total_hours, 24) # 本程序應用方式
程序實例ch3_25.py:使用divmod( )函數重新設計ch3_24.py。

執行結果 與ch3_24.py相同。
3-7-2 計算坐標軸兩個點之間的距離
有兩個點坐標分別是(x1, y1)、(x2, y2),這兩個點的距離計算公式如下。

可以將上述公式轉成下列計算機數學表達式。
dist = ( (x1 – x2)2 + (y1 – y2)2 ) ** 0.5 # ** 0.5相當于開根號
在人工智能的應用中,常用點坐標代表某一個對象的特征(feature),計算兩個點之間的距離,相當于可以了解物體間的相似程度。距離越短代表相似度越高,距離越長代表相似度越低。
程序實例ch3_26.py:有兩個點坐標分別是(1, 8)與(3, 10),請計算這兩個點之間的距離。

執行結果

習題
1. 假設a是10,b是 18,c是5,請計算下列執行結果,取整數結果。(3-2節)
(a) s = a + b – c
(b) s = 2 * a + 3 – c
(c) s = b * c + 20 / b
(d) s = a % c * b + 10
(e) s = a ** c – a * b * c

2. 請重新設計第2章習題2,請使用int( )函數,以整數列出本金和。(3-2節)

3. 請重新設計第2章習題2,使用round( )函數,以整數列出本金和。(3-2節)

4. 地球和月球的距離是384 400千米,假設火箭飛行速度是每分鐘250千米,請問從地球飛到月球需要多少天、多少小時、多少分鐘,請舍去秒鐘。(3-2節)

5. 請列出你自己名字十進制的Unicode碼值。(3-5節)

6. 請列出你自己名字十六進制的Unicode碼值。(3-5節)

7. 請將Unicode字符串“Python王者歸來”轉成bytes數據,然后輸出bytes數據。(3-6節)

8. 重新設計ch3_25.py,需計算至分鐘與秒鐘數。(3-7節)

9. 請修改ch3_26.py,計算這兩個點坐標(1, 8)與(3, 10)距坐標原點(0, 0)的距離。
