第三章Python基礎
Python使用縮進來組織代碼塊,請務必遵守約定俗成的習慣,堅持使用4個空格的縮進。
在文本編輯器中,需要設置把Tab自動轉換爲4個空格,確保不混用Tab和空格。
3.1 數據類型和變量
1、整數
2、浮點數
3、字符串
(1)字符串是以單引號'或雙引號"括起來的任意文本;
(2)如果'本身也是一個字符,那就可以用""括起來,比如"I'm OK"包含的字符是I,',m,空格,O,K這6個字符。
(3)如果字符串內部既包含'又包含"怎麼辦?可以用轉義字符\來標識。
(4)轉義字符\。基本上與C語言的一致
(5)python允許使用r‘’表示‘’內部的字符串默認不轉義。
>>>print(r’\\\t\\’)
(6)如果字符串內部有很多換行,用\n寫在一行裏不好閱讀,爲了簡化,python允許使用’’’…’’’的格式表示多行內容。
>>> print('''line1
... line2
... line3''')
line1
line2
line3
如果寫成程序
print(
'''line1
line2
line3''')
1、 布爾值(True、False)
布爾值可以用and,or,not運算
2、 空值
空值是Python裏一個特殊的值,用None表示。None不能理解爲0,因爲0是有意義的,而None是一個特殊的空值。
3、 列表、字典、創建自定義數據類型
4、 變量
在Python中,等號=是賦值語句,可以把任意數據類型賦值給變量,同一個變量可以反覆賦值,而且可以是不同類型的變量,例如:
a = 123 # a是整數
print(a)
a = 'ABC' # a變爲字符串
print(a)
5、 常量
在Python中,通常用全部大寫的變量名錶示常量:
PI = 3.14159265359
但事實上PI仍然是一個變量,Python根本沒有任何機制保證PI不會被改變,所以,用全部大寫的變量名錶示常量只是一個習慣上的用法,如果你一定要改變變量PI的值,也沒人能攔住你。
9、地板除(//)和取餘(%)
10//3 = 3;10%3=1
【小結】
(1)Python支持多種數據類型,在計算機內部,可以把任何數據都看成一個“對象”,而變量就是在程序中用來指向這些數據對象的,對變量賦值就是把數據和變量給關聯起來。
(2)注意:Python的整數沒有大小限制,而某些語言的整數根據其存儲長度是有大小限制的,例如Java對32位整數的範圍限制在-2147483648-2147483647。
(3)Python的浮點數也沒有大小限制,但是超出一定範圍就直接表示爲inf(無限大)。
3.2 字符串和編碼
1、ASCII,Unicode,UTF-8
(1)ASCII:最早只有127個字符被編碼到計算機裏,也就是大小寫英文字母、數字和一些符號,這個編碼表被稱爲ASCII編碼。
(2)Unicode:Unicode把所有語言都統一到一套編碼裏,這樣就不會再有亂碼問題了。Unicode標準也在不斷髮展,但最常用的是用兩個字節表示一個字符(如果要用到非常偏僻的字符,就需要4個字節)。現代操作系統和大多數編程語言都直接支持Unicode。
(3)UTF-8:如果統一成Unicode編碼,亂碼問題從此消失了。但是,如果你寫的文本基本上全部是英文的話,用Unicode編碼比ASCII編碼需要多一倍的存儲空間,在存儲和傳輸上就十分不划算。
所以,本着節約的精神,又出現了把Unicode編碼轉化爲“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字符根據不同的數字大小編碼成1-6個字節,常用的英文字母被編碼成1個字節,漢字通常是3個字節,只有很生僻的字符纔會被編碼成4-6個字節。如果你要傳輸的文本包含大量英文字符,用UTF-8編碼就能節省空間。
ASCII編碼實際上可以被看成是UTF-8編碼的一部分,所以,大量只支持ASCII編碼的歷史遺留軟件可以在UTF-8編碼下繼續工作。
(4)下現在計算機系統通用的字符編碼工作方式:
在計算機內存中,統一使用Unicode編碼,當需要保存到硬盤或者需要傳輸的時候,就轉換爲UTF-8編碼。
用記事本編輯的時候,從文件讀取的UTF-8字符被轉換爲Unicode字符到內存裏,編輯完成後,保存的時候再把Unicode轉換爲UTF-8保存到文件:
瀏覽網頁的時候,服務器會把動態生成的Unicode內容轉換爲UTF-8再傳輸到瀏覽器:
2、Python字符串
(1)Python 3版本中,字符串是以Unicode編碼的,也就是說,Python的字符串支持多語言。
(2)對單個字符的編碼,ord()函數獲取字符的整數表示,chr()函數把編碼轉換成對應的字符
(3)如果知道字符的整數編碼,還可以用十六進制這麼寫str:
>>> '\u4e2d\u6587'
'中文'
(4)由於python的字符串類型是str,在內存中以Unicode表示,一個字符對應若干個字節。如果要在網絡上傳輸,或者保存到磁盤上,就需要把str變爲以字節爲單位的bytes。
python對bytes類型的數據用帶b前綴的單引號或雙引號表示:
x=b’ABC’
(5) 以Unicode表示的str通過encode()方法可以編碼爲指定的bytes.
>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')
Traceback (most recent call last):
File"<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters inposition 0-1: ordinal not in range(128)
純英文的str可以用ASCII編碼爲bytes,內容是一樣的,含有中文的str可以用UTF-8編碼爲bytes。含有中文的str無法用ASCII編碼,因爲中文編碼的範圍超過了ASCII編碼的範圍,Python會報錯。
在bytes中,無法顯示爲ASCII字符的字節,用\x##顯示。
(6) 反過來,如果我們從網絡或磁盤上讀取了字節流,那麼讀到的數據就是bytes。要把bytes變爲str,就需要用decode()方法:
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
(7)len()函數計算的是str的字符數,如果換成bytes,len()函數就計算字節數。
可見,1箇中文字符經過UTF-8編碼後通常會佔用3個字節,而1個英文字符只佔用1個字節。
(8)在操作字符串時,我們經常遇到str和bytes的互相轉換。爲了避免亂碼問題,應當始終堅持使用UTF-8編碼對str和bytes進行轉換。
(9)由於Python源代碼也是一個文本文件,所以,當你的源代碼中包含中文的時候,在保存源代碼時,就需要務必指定保存爲UTF-8編碼。當Python解釋器讀取源代碼時,爲了讓它按UTF-8編碼讀取,我們通常在文件開頭寫上這兩行:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
第一行註釋是爲了告訴Linux/OS X系統,這是一個Python可執行程序,Windows系統會忽略這個註釋;
第二行註釋是爲了告訴Python解釋器,按照UTF-8編碼讀取源代碼,否則,你在源代碼中寫的中文輸出可能會有亂碼。
申明瞭UTF-8編碼並不意味着你的.py文件就是UTF-8編碼的,必須並且要確保文本編輯器正在使用UTF-8 without BOM編碼:
(10)格式化
在Python中,採用的格式化方式和C語言是一致的,用%實現。
常見的佔位符有:
%d 整數
%f 浮點數
%s 字符串
%x 十六進制整數
其中,格式化整數和浮點數還可以指定是否補0和整數與小數的位數:
>>> '%2d-%02d' % (3, 1)
' 3-01'
>>> '%.2f' % 3.1415926
'3.14'
如果你不太確定應該用什麼,%s永遠起作用,它會把任何數據類型轉換爲字符串:
>>> 'Age: %s. Gender: %s' % (25, True)
'Age: 25. Gender: True'
有些時候,字符串裏面的%是一個普通字符怎麼辦?這個時候就需要轉義,用%%來表示一個%:
>>> 'growth rate: %d %%' % 7
'growth rate: 7 %'
【小結】
Python 3的字符串使用Unicode,直接支持多語言。
str和bytes互相轉換時,需要指定編碼。最常用的編碼是UTF-8。Python當然也支持其他編碼方式,比如把Unicode編碼成GB2312:
>>> '中文'.encode('gb2312')
b'\xd6\xd0\xce\xc4'
但這種方式純屬自找麻煩,如果沒有特殊業務要求,請牢記僅使用UTF-8編碼。
格式化字符串的時候,可以用Python的交互式命令行測試,方便快捷。
3.3 使用list(列表)和tuple(字典)
1、list(列表)
(1)list是一種有序的集合,可以隨時添加和刪除其中的元素。
>>> classmates = ['Michael', 'Bob', 'Tracy']
(注意使用的是[])
classname就是一個list
(2)len()函數可以獲得list元素的個數
len(classname)
(3)用索引來訪問list中每個位置的元素,索引是從0開始的
classname[0],classname[1]
(4)要取得最後一個元素,還可以用-1做索引,直接獲取最後一個元素
>>>classname[-1]
以此類推,可以獲取倒數第2個、倒數第3個:
(1)append()函數追加元素到末尾
>>>classname.append(‘mike’)
(7)insert()函數可以把元素插入到指定的位置,比如索引號爲i的位置
classname.insert(2,‘david’)
(8)pop()函數刪除list末尾的元素
classname.pop()
要刪除指定位置的元素,用pop(i)方法,其中i是索引位置:
(9)要把某個元素替換成別的元素,可以直接賦值給對應的索引位置
Classname[1]=’sary’
(10)list裏面元素的數據類型可以不同
L=[‘APPLE’,1234,True]
(11)list元素也可以是另一個list
s=[‘python’,’java’,[‘asp’,’php’]]
其中s[2][1]=’php’
(12)如果一個list中一個元素都沒有,就是一個空的list,長度爲0.
L=[]
>>>Len(L)
0
2、tuple(元組)
tuple一旦初始化後就不能修改。
>>>classname=(‘mike’’david’’jone’)
(1) tuple沒有insert(),append(),pop()這些方法
(2) 獲取元素的方法和list一樣,classname[0],classname[-1]
(3) tuple的意義:因爲tuple不變,所以代碼更安全,如果有可能,能用tupledaitilist就儘量使用tuple
(4) tuple陷阱:當定義一個tuple時,tuple元素就必須確定下來
(5) 如果要定義一個空的tuple,可以寫成():
>>>t = ()
(6)只有1個元素的tuple定義時必須加一個逗號,,來消除歧義:
>>>t = (1,)
Python在顯示只有1個元素的tuple時,也會加一個逗號,,以免你誤解成數學計算意義上的括號。
(7)可變的tuple
>>>t = (‘a’,’b’,[‘A’,’B’])
t[2][0]=’mike’
t[2][1]=’jone’
>>>t
(‘a’,’b’,[‘mike’,’jone’])
【小結】
list和tuple是python內置的有序集合,一個可變,一個不可變。根據需要來選擇它們。
3.4 條件判斷
1、if, if…else, if…elseif…if
(1)if語句【注意:不要忘了if語句後面要添加‘:’】
用if語句實現條件判斷:
age = 20
if age >= 18:
print('your age is',age)
print('adult')
(2)if… else語句
age = 3
if age >= 18:
print('your age is',age)
print('adult')
else:
print('your age is',age)
print('teenager')
(3)elseif
可以用elif做更細緻的判斷:
age = 3
if age >= 18:
print('adult')
elif age >= 6:
print('teenager')
else:
print('kid')
elif是else if的縮寫,完全可以有多個elif,所以if語句的完整形式就是:
if <條件判斷1>:
<執行1>
elif <條件判斷2>:
<執行2>
elif <條件判斷3>:
<執行3>
else:
<執行4>
2、再議input()
birth = input('birth: ')
if birth < 2000:
print('00前')
else:
print('00後')
輸入1982,結果報錯:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() > int()
這是因爲input()返回的數據類型是str,str不能直接和整數比較,必須先把str轉換成整數。
Python提供了int()函數來完成這件事情:
s = input('birth: ')
birth = int(s)
if birth < 2000:
print('00前')
else:
print('00後')
3.5 循環
循環有兩種型式:
1、 for…in
依次把list或者tuple中的每個元素迭代出來
names = ['Michael', 'Bob', 'Tracy']
for name in names:
print(name)
python提供一個range()函數,可以生成一個整數序列,再通過list()函數可以轉換爲list。
2、 while
第二種循環是while循環,只要條件滿足,就不斷循環,條件不滿足時退出循環。
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
3、 break
在循環中,break語句可以提前退出循環。
如果要提前結束循環,可以用break語句:
n = 1
while n <= 100:
if n > 10: # 當n = 11時,條件滿足,執行break語句
break # break語句會結束當前循環
print(n)
n = n + 1
print('END')
4、 continue
在循環過程中,也可以通過continue語句,跳過當前的這次循環,直接開始下一次循環。
n = 0
while n < 10:
n = n + 1
if n % 2 == 0: # 如果n是偶數,執行continue語句
continue #continue語句會直接繼續下一輪循環,後續的print()語句不會執行
print(n)
continue的作用是提前結束本輪循環,並直接開始下一輪循環。
3.6 使用dict和set
1、字典dict{}
(1)在其他語言中稱爲map,使用鍵-值(key-value)存儲
>>>d = {‘mike’:95,’bob’:75,’tracy’:85}
>>>d[‘mike’]
95
(2)把數據放入dict的方法,除了初始化時指定外,還可以通過key放入:
>>> d['Adam'] = 67
(3)由於一個key只能對應一個value,所以,多次對一個key放入value,後面的值會把前面的值沖掉.
(4)如果key不存在,dict就會報錯
(5)要避免key不存在的錯誤,有兩種辦法,
一是通過in判斷key是否存在:
>>> 'Thomas' in d
False
二是通過dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value:
>>> d.get('Thomas')
>>> d.get('Thomas', -1)
-1
注意:返回None的時候Python的交互式命令行不顯示結果。
(6)要刪除一個key,用pop(key)方法,對應的value也會從dict中刪除:
(7)請務必注意,dict內部存放的順序和key放入的順序是沒有關係的。
(8)和list比較,dict有以下幾個特點:
查找和插入的速度極快,不會隨着key的增加而變慢;
需要佔用大量的內存,內存浪費多。
而list相反:
查找和插入的時間隨着元素的增加而增加;
佔用空間小,浪費內存很少。
所以,dict是用空間來換取時間的一種方法。
(9)dict可以用在需要高速查找的很多地方,在python代碼中幾乎無處不在,正確使用dict非常重要,需要牢記的第一條就是dict的key必須是不可變對象。
(10)通過key計算位置的算法稱爲哈希算法(Hash)。
要保證hash的正確性,作爲key的對象就不能變。在Python中,字符串、整數等都是不可變的,因此,可以放心地作爲key。而list是可變的,就不能作爲key。
2、set
(1)set和dict類似,也是一組key的集合,但不存儲value。由於key不能重複,所以,在set中,沒有重複的key。
要創建一個set,需要提供一個list作爲輸入集合:
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}
注意,傳入的參數[1, 2, 3]是一個list,而顯示的{1, 2, 3}只是告訴你這個set內部有1,2,3這3個元素,顯示的順序也不表示set是有序的。
(2)重複元素在set中自動被過濾:
>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}
(3)通過add(key)方法可以添加元素到set中,可以重複添加,但不會有效果。
(4)通過remove(key)方法可以刪除元素。
(5)set可以看成數學意義上的無序和無重複元素的集合,因此,兩個set可以做數學意義上的交集、並集等操作:
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}
(6)set和dict的唯一區別僅在於沒有存儲對應的value,但是,set的原理和dict一樣,所以,同樣不可以放入可變對象,因爲無法判斷兩個可變對象是否相等,也就無法保證set內部“不會有重複元素”。
3.7 再議不可變對象
str是不變對象,list是可變對象
對於不可變對象str的操作:
>>> a = 'abc'
>>> a.replace('a','A')
'Abc'
>>> a
'abc'
等價於下面:
>>> a = 'abc'
>>> b =a.replace('a', 'A')
>>> b
'Abc'
>>> a
'abc'
【小結】
使用key-value存儲結構的dict在Python中非常有用,選擇不可變對象作爲key很重要,最常用的key是字符串。