2017-10-11

Python Tutorial–Lesson 1: Data types, variables, and operators 資料型態、變數和運算子

Python 自學教材的第1課,讓我們先從最基礎開始,Python 語言的資料型態、變數設定和數字、比較、邏輯運算子。


學習目標:
  • Data Types 資料型態
  • Variables 變數
  • Operators 運算子
學習一種新的電腦語言,先確定動機似乎是個重要的開始。程式語言具有比較強的實用性與目的性(簡單的說就是會比較無聊),若能了解該程式語言的實用價值,可能會對提高學習動機有幫助。因此這裡也不免俗的列出 Python 語言的一些特性,但這些特性絕非只有 Python 才具有,別的語言都辦不到;也絕非意指 Python 是最佳的程式語言。
Features of Python:
  • Python is free.
  • Python is available for all major OS.
  • Python is easy to learn.
  • Python is powerful and flexible.
  • Python has healthy, active and supportive communities.
  • There are many useful standard library and modules in Python.
Python 相對於C、C++、C#、Java是相當簡單易學的電腦程式語言,而且語言本身就寓涵了相當好的程式設計哲學,加上強大的第三方社群,豐富又完整的免費套件,以及在科學、學術領域長久且廣泛的運用,Python 絕對在適合初學程式設計的電腦語言中排得上名次。
接下來就開始學習 Python 的第一課。學習程式設計,一定要親手實作和執行程式,本文提供了非常多範例,黑色底的區塊均為程式碼,您可以輕易的複製執行,只要將程式碼複製,貼到 Python IDLE 或Jupyter Notebook中執行就可以了。光看程式碼的學習效果並不好,所以您至少一定要有 Python IDLE,若能有 Jupyter Notebook 就更棒了,您可以透過 Anaconda Distribution 來取得學習 Python 需要的完整工具,請參考《Python 超強套件包 - Anaconda Distribution》;Jupyter Notebook 的簡單操作介紹,則可參考《學習 Python 不可不知的開發工具 IPython 和 Jupyter Notebook》。工欲善其事、必先利其器,把工具準備好,就可以開工了。

Data Types & Variables (資料型態與變數)
電腦程式語言簡單的說就是資料、流程控制與函數的集合。1984年圖靈獎得主,瑞士電腦科學家 Niklaus Wirth 的重要著作《Algorithms + DataStructures = Programs》為電腦程式下了極簡的經典定義,程式=演算法+資料結構。我們運用電腦來協助處理複雜、大量的資料,流程控制與函數是處理資料的過程也就是演算法,這兩者合在一起就是程式了。所以資料是我們第一個要了解的。
Python的資料型態非常簡單,相對於Java這種強型別(strongly typed)的語言,Python (也有人認為Python是強型別語言,這是因為對強弱型別並沒有非常明確的定義,這裡指的是對資料型態宣告、使用、管控的程度)的資料型態相當容易了解,也很容易掌握,但有得就有失,後面會用例子讓大家了解。我們可以把Python的資料型態概略分成基本資料型態和抽象資料型別如下:
(註:在學習程式語言的初期您可能會看到很多不懂的名詞,請不要被它們困擾。文中會加上相關連結,若有興趣就去看看,沒興趣就不要理它,不懂它們並不會影響您的學習,學習的關鍵是好玩,而不是被一堆東西弄到沒胃口,需要您了解時會進一步說明。)
基本資料型態:
  • Numbers數值 (int 整數,float 浮點數,complex 複數)
  • Strings 字串
  • Boolean 布林
  • None 空值
抽象資料型別:
  • List
  • Tuple
  • Set
  • Dictionary

Numbers 數值
Python Numbers 就只有整數和浮點數兩種 (註1),您設定的數值資料只要沒有小數點,它就是整數;有小數點或小數點後的數字,就是浮點數。 Python 的整數沒有特定的大小限制,取決於執行的記憶體空間。 Python 浮點數採用 IEEE-754 雙精度浮點數 (double precision) 可保證十進位制小數點後15位有效數字。您不用像在 Java 這類程式語言中要去擔心設定變數的容量大小, Python 的設計哲學就是「優雅、簡單」,強調直覺的運用,不要想太多。 需要注意的是整數和浮點數的型態轉換 (type conversion),當您在作運算時如 3/2=1.5 原本2個數值都是整數,但運算後會變成浮點數,這通常會在您要作比較判斷時會有影響。
簡單的規則如下:
  • 四則運算中有使用到浮點數,結果就會變成浮點數。
  • 除法會自動變成浮點數。
試試以下的例子:
# Python numbers examples  @author: Sean Lu.
a=1.			# = 就是設定(assignment),設定變數a的值是1.(注意這裡僅有小數點)
print(a)		# 只要有小數點,就是浮點數
print(1+1.0)		# 和浮點數作四則運算,結果會變浮點數
print(2-1.0)		# 和浮點數作四則運算,結果會變浮點數
print(2*1.0)		# 和浮點數作四則運算,結果會變浮點數
print(2/1.0)		# 和浮點數作四則運算,結果會變浮點數
print(4/2)		# 進行除法,即使是整除也還是會變浮點數
除了運算的過程中整數有可能自動轉換成浮點數,也可以自行控制型態轉換,使用 int() 將字串或浮點數轉成整數,以 float() 將字串或整數轉成浮點數,看看以下的例子:
# Python type conversion function examples  @author: Sean Lu.
a=3      # 這是整數
b='3'    # 這是字串
c=3.33   # 這是浮點數
d='3.33' # 這是字串
print(float(a)+1)  # 將整數轉浮點數
print(int(b)+1)    # 將字串轉整數
print(int(c)+1)    # 將浮點數轉整數
print(float(d)+1)  # 將字串轉浮點數
(註1) Python 的數值型態其實還有一個 complex 複數,如果您跟我一樣完全不懂複數是什麼,恭禧,不用懂它,因為完全用不到。如果您是那種不懂會很痛苦的人,只要知道Python 大量運用在數學研究領域,complex 複數是給數學家和科學家用的就可以了。

Strings 字串
Python Strings 就只有字串一種型態,沒有字元(character)。只要用英文的引號(quote)包括起來就是字串的設定(assignment),您要用單引號(')或雙引號(")都可以,但請不要各用一個。字串也有運算,(+) 加號是字串的連接(concatenation),但注意加號的兩邊都必須是字串;(*) 乘號是字串的重複(replication),*5 就是重複5次。試試以下的例子:
# Python strings examples  @author: Sean Lu.
a='a'				# 1個字元也是字串
b='This is string'		# 使用單引號ok
c="This is string, too"		# 使用雙引號ok
# d='This is not OK!"		# 前單後雙不ok,前雙後單也不ok
print(a+' and b')		# (+) 加號將字串連接
print(b*3)			# (*) 乘號將字串重複
# print(a+3)			# 字串加號的兩邊都必須是字串,不ok
str() 是字串型態轉換(type conversion)函數,將括號內的參數轉換成字串。剛剛的例子:
# Python string type conversion examples  @author: Sean Lu.
a='a'			# a 是字串
# print(a+3) 		# 字串加號的兩邊都必須是字串,不ok
print(a+str(3)) 	# str()將整數3轉換成字串,ok
print(a+str(3.3)) 	# str()將浮點數3.3轉換成字串,ok
字串在 Python 中視為字元的組合,而且是有序的組合,可以像是陣列(array)或是後面會介紹到的 List 資料型態透過索引(index)來使用字串的內容。這是字串很重要的特性,意味著我們可以從字串中尋找、定位、取出、重組字串中的資料。但要注意一點 Python 的字串是不可變(immutable)的,不可變的意思是字串被設定後就不可改變裡面的內容,想要改變字串內容,只能重新設定。字串的索引定位是從 0 開始,也可以反向定位由 -1 開始。我們看看下圖的字串和以下的例子:

p
y
t
h
o
n
_
p
r
o
g
r
a
m
正向
0
1
2
3
4
5
6
7
8
9
10
11
12
13
反向
-14
-13
-12
-11
-10
-9
-8
-7
-6
-5
-4
-3
-2
-1
# Python string examples  @author: Sean Lu.
str = 'python_program'
print('str=', str)
print('str[0] =', str[0])       # 取出字串的第1個項目
print('str[-1] =', str[-1])     # 取出字串的最後1個項目
print('str[1:6] =', str[1:6])   # 取出由1的位置開始,結束於6的字串
print('str[5:-2] =', str[5:-2]) # 取出由5的位置開始,結束於-2的字串
print('str[0:8] =', str[0:8])   # 取出由0的位置開始,結束於8的字串
print('str[:8] =', str[:8])     # 同上取出由0的位置開始,結束於8的字串
print('str[7:] =', str[7:])     # 取出由7的位置開始,到最後的字串
str[0] = 'q'                    # 將字串的第1個字元'p'改成'q',這不可行,會出現錯誤訊息,因為字串不可變
這個例子的最後一個指令試圖將字串的第1個字元'p'改成'q',這是不行的,Python 會丟出 TypeError 錯誤訊息 'str' object does not support item assignment,告訴我們字串無法作內容項目設定,因為字串是不可變(immutable)的。
在例子中您常會見到 (#) 井字號 (hash character),這是 Python 的單行註解(comment),在(#)後的該行文字會被 Python 視為註解文字,而不作任何處理。在程式中隨時加上註解是很好的程式設計習慣,建議要養成這個習慣。Python 還有以(""")三個雙引號或(''')三個單引號作為多行註解,但這同時也是 Python 設定多行字串的標註方式,容易混淆,所以建議您採用 Python 的設計哲學,用一種註解方法就好了,(#) 井字號是很好的選擇,也是大部份程式設計師的選擇。
# Python comment examples  @author: Sean Lu.
# 建議一定要養成加註解的習慣,寫成一行 ok
a='This is a string'   # a 設定字串變數,寫在程式之後也 ok

"""
3個雙引號是多行註解,包在兩組3個雙引號間的都會被視為註解,不管幾行,
建議您使用一種方式就好。
a='a string'
"""
'''三個單引號也是多行註解,
以三個單引號包含
a=1
'''
b=1         # b 設定整數變數
print(a)    # 雖然在註解中都對a變數重新作了設定,但它們都是註解,不會造成影響,a 還是一開始的設定a='This is a string'
# 以下是設定多行字串
helloMessage="""
***********************
歡迎來到 Python 的世界
相信您一定會喜歡上 Python
***********************
"""
print(helloMessage)
最後一個 helloMessage 變數就是使用3個雙引號設定多行字串內容,一樣也可以用3個單引號。多行註解和多行字串的標註方式相同,建議養成習慣用一種方式就好,註解就用 (#) 井字號,多行字串用3個引號,免得弄混。Boolean 布林和 None 空值以及抽象資料型別,先不理它們,等到後面需要用到時再介紹,接下來介紹變數。

Variable 變數
變數是程式用來儲存資料(或稱之為值/內容)的地方,您可以將它想像成是一個盒子或一個存放的空間,裡面放著您設定的資料,而把資料放進盒子這個動作就是變數設定(assignment),把資料設定給某個變數。因為是一個盒子,所以裡面的資料是可以拿出來(讀出)、放進去(設定/改變),也可以銷毀(清除)。Python 使用變數不需事先宣告及指定資料型態,只要以 (=) 等號(設定運算子,assignment operator) 設定變數及其資料就可以使用。
介紹數值和字串時已經看過設定數值變數和字串變數的方式,這裡要說明的是 Python 的變數命名規則:
  • 變數名可以使用英文字母、數字和底線符號(_)。
  • 可以只有一個英文字母。
  • 可以英文字母或底線符號(_)開頭,但不能以數字開頭。
  • 不能用 Python 保留字當變數名。
這個其實不算變數命名規則之一,但這是 Python 的通則,變數英文字母大小寫是不同的(case-sensitive)
下表是 Python 的保留字,其實就是 Python 已用在程式指令中的關鍵字,當然不能直接用這些字來當變數名稱,不然 Python 怎麼分辨到底是指令還是變數?不過加上其它字組合就可以用喔,比如說 return 是保留字不能當變數,但改成這樣 returnValue 就可以當變數名了。在程式中自訂的變數和函數名(function name)都同樣依循這個命名規則。

以下的變數名都是正確的(valid)
_(只有一個底線符號當變數名,這個變數名挺怪的,但是可以喔!), a, a1, apple, _apple, apple8, apple_x, iLikeApple, i_Like_Apple_Very_Much
以下的變數名則是不正確的(invalid)
8apple # 不可以是數字開頭
48 # 不可以是數字開頭,只有數字當然也不可以
apple-x # 符號只能用底線符號(_)
apple x # 不可以有空白
以下是變數設定的範例:
# Python variable assignment examples  @author: Sean Lu.
newFile='inputdata.txt'	 # 設定一個檔案名,字串型態
newData=''		 # 設定一個空字串
counterA_01=0		 # 設定一個值為0的整數 counter
interestRate=0.01	 # 設定interestRate利率變數為浮點數0.01
a,b,c=1,2,'Jack'	 # 多重設定(multiple assignment),同時設定a=1,b=2,c='Jack'
d=e=f=0			 # 也是多重設定,同時設定d,e,f變數都為0
print(a)
print(b)
print(c)
print(d)
print(e)
除非您使用的變數意義都相同,不然最好避免使用多重設定(multiple assignment),雖然寫在一起很方便,也節省行數,但您就不容易對每個變數加上說明註解。最好還是一行一行設定,並對每個變數加上說明註解。同時使用有意義的變數名,增加程式的可讀性且避免出錯。

Operator 運算子
也稱為運算元,將介紹數學運算子(math operators)、比較運算子(comparison operators)和邏輯運算子(logical operators) (註2)
數學運算子
例子
**  次方
餘數
//
除法
乘法
減法
加法
2 ** 4     24次方 = 16
22 % 4    224的餘數 = 2
22 // 4   224的商 = 5
22 / 4    224 = 5.5
5 * 4     54 = 20
5 - 4     54 = 1
5 + 4     54 = 9

這張表的數學運算子順序同時就是它們的優先序(precedencd),次方優先最高,加法最低,但建議您在複雜的運算式裡盡量使用括號來控制優先序,雖然您一定知道優先序的處理,但人都有看錯的時候,使用括號來避免出錯的機會。
# Python math operator examples  @author: Sean Lu.
2 + 3 * 4
(2 + 3) * 4
(50 - 5*6) / 4
((2 ** 3) * 4) + 10  # 盡量使用括號來控制優先序
-3**2                # (**)次方的優先序高於(-)負號,所以值是-9
若您有 Java 程式設計經驗,可能很習慣 i++, i--, ++i, --i 這些在 Java 中非常方便的遞增/遞減運算子,但在 Python 中可沒有喔。不過在 Python i += 1 (i = i + 1) 則是可以的。
i += 1 意即 (i = i + 1)
i -= 1 意即 (i = i - 1)
i *= 1 意即 (i = i * 1)
i /= 1 意即 (i = i / 1)

比較運算子
例子
==  等於,判斷是否相等
!=  不等於,判斷是否不相等
大於,判斷是否大於
小於,判斷是否大於
>=  大於等於,判斷是否大於
<=  小於等於,判斷是否大於
2==2    2是否等於2,真(True)
‘a’!=’ab’  ‘a’是否不等於’ab’,真(True)
2>10    2是否大於10,偽(False)
2<10 2="" nbsp="" span="">是否小於10,真(True)
10>=10  10是否大於等於10,真(True)
2<=10   2是否小於等於10,真(True)

數學運算子的結果是數學運算的值,比較運算子的結果則是比較判斷的真偽,即是接下來要介紹的另一個基本資料型態-布林。

Python Boolean 布林,這個資料型態只有True()False()兩個值,布林是比較運算和邏輯運算的結果,它是流程控制的重要元素,也是程式邏輯判斷的基礎,非常重要。True即是「真」,您也可以想成是「成立」或「是」,False是「偽/假」、「不成立」或「非」。談到布林,我們就必須介紹邏輯運算子(logical operators)和真值表(truth table)

邏輯運算子
例子
and  
or   
not  
and 運算子的兩邊均為「真」,結果才為「真」,否則為「偽」
or 運算子的兩邊只要有一邊為「真」,結果即為「真」。
not 運算子用以否定另一布林,非「真」即「偽」,非「偽」即「真」。

因為邏輯運算子的兩邊會有「真」、「偽」各 2x2=4 種狀況,所以會有真值表(truth table)用以邏輯判斷,這在所有的電腦語言和邏輯判斷都是相同的喔。

and 真值表
結果
True  and  True
True  and  False
False  and  True
False  and  False
True
False
False
False

or 真值表
結果
True  or  True
True  or  False
False  or  True
False  or  False
True
True
True
False

not 真值表
結果
not True
not False
False
True

邏輯判斷很簡單,一定難不倒您,但非常重要喔!試一下這些例子:
# Python comparison and logical operator examples  @author: Sean Lu.
50 == 50
45 == 99
3 != 5
3 != 3
'hello' == 'hello'
'hello' == 'Hello'
'dog' != 'cat'
True == True   # Boolean也可以比較喔
True != False  # Boolean也可以比較喔
42 == 42.0     # 試試看42是否等於42.0?
42 == '42'     # 42和’42’呢?
(4 < 5) and (5 < 6)
(4 < 5) and (9 < 6)
(1 == 2) or (2 == 2)
2 + 2 == 4 and not 2 + 2 == 5 and 2 * 2 == 2 + 2   # 試試看複雜一點的吧
(2) 邏輯運算子也被稱為布林運算子(boolean operators),Python 的運算子還有位元運算子及 is, is not, in, not in等,我們等介紹到需要運用的地方再來說明它們的用途。
前面提到過 Python 不需宣告變數資料型態,設定就可以使用了。這讓 Python 的變數使用有很大的彈性,但有時可能也會有問題喔,來看看這個例子:
# Python variable assignment examples  @author: Sean Lu.
s='s is a string'  # (1) 變數 s 是字串
a=10               # 變數 a 是整數 10
b=a+1              # 變數 b 的資料型態?
s=b                # (2) What happens to s? (s原本是字串喔!)
print('b=',b)
print('s=',s)
(1)位置設定變數s為字串's is a string',這個動作稱為變數的初始設定或初始化(initialized),我們第一次為變數s設定值,其後的變數a和變數b也都是初始設定。(2)的位置則是重新設定了變數s=變數b,也稱為對變數s進行覆寫(overwriting),那這時變數s會變成什麼呢?答案是整數11,內容值和資料型態都改變了。因為 Python 不需宣告變數資料型態,所以在程式的過程中,變數的資料型態是可能改變的。您必須特別注意變數的資料型態是否都在您的掌握中,不然資料型態若改變了,比較運算的結果可就不一樣囉!回想一下前面 42 == '42' 這個例子,結果是False,數值和字串是不相等的喔。
您若掌握了資料型態、變數和運算子,就可以進到下一章流程控制(Flow Control)囉!

參考資料: