1.解釋器
編譯器或者解釋器就是負責把符合文法的程式代碼轉換成CPU能夠執行的機器碼,然後執行。Python也不例外。同時Python解釋器承擔了記憶體管理的複雜任務,這大大簡化了應用程式的編寫。
Python的解釋器有很多,有CPython,IPython,PyPy,Jython,IronPython等。其中 CPython是使用最廣的Python解釋器。教程的所有代碼也都在CPython下執行。( CPython用>>>作為提示符,而IPython用In [序号]:作為提示符。)
2.文法特點
以#開頭的語句是注釋,注釋是給人看的,可以是任意内容,解釋器會忽略掉注釋。其他每一行都是一個語句,當語句以冒号:結尾時,縮進的語句視為代碼塊。
Python程式是大小寫敏感的,如果寫錯了大小寫,程式會報錯。
3. 資料類型
python能夠直接處理的資料類型有:
3.1 整數(包括負整數):
數學方法表示:1,100,-8080,0,等等。
用十六進制表示: 十六進制用0x字首和0-9,a-f表示,例如:0xff00,0xa5b4c3d2,等等。
3.2 浮點數(小數):
數學方法表示: 如1.23,3.14,-9.01,等等。用科學計數法表示(很大/很小的浮點數): 把10用e替代,1.23x109就是1.23e9,或者12.3e8,0.000012可以寫成1.2e-5,等等。注: 整數和浮點數在計算機内部存儲的方式是不同的,整數運算永遠是精确的(除法難道也是精确的?是的!),而浮點數運算則可能會有四舍五入的誤差。
3.3 字元串:
字元串是以單引号'或雙引号"括起來的任意文本,需要注意的是 ''或""本身隻是一種表示方式,不是字元串的一部分。
(1):如果'本身也是一個字元,那就可以用""括起來
(2):如果字元串内部既包含'又包含"則可以用轉義字元\來辨別。比如 'I\'m \"OK\"!'
(3):轉義字元\可以轉義很多字元,比如\n表示換行,\t表示制表符,字元\本身也要轉義,是以\\表示的字元就是\。
(4):如果字元串裡面有很多字元都需要轉義,就需要加很多\,為了簡化,Python還允許用r''表示''内部的字元串預設不轉義。比如
>>> print(r'\\\t\\')\\\t\\
(5):字元串内部有很多換行,用\n寫在一行裡不好閱讀,為了簡化,Python允許用'''...'''的格式表示多行内容。比如
>>> print('''line1... line2... line3''')line1line2line3
(6):字元編碼: 字元串比較特殊的是還有一個編碼問題
- 曆史:
最早計算機采用8bit作為一個位元組(byte),是以一個位元組能表示的最大的整數是255(二進制11111111=十進制255),如果要表示更大的整數,就必須用更多的位元組。比如兩個位元組可以表示的最大整數是65535,4個位元組可以表示的最大整數是4294967295。
最早出現的是ASCII編碼,隻有127個字元被編碼到計算機裡,也就是大小寫英文字母、數字和一些符号。可是這個要進行中文的話,就需要兩個位元組,而且還不能和ASCII碼沖突。
中國制定了GB2312編碼,用來把中文編進去。日本把日文編到Shift_JIS裡,南韓把韓文編到Euc-kr裡,各國有各國的标準,就會不可避免地出現沖突,結果就是,在多語言混合的文本中,顯示出來會有亂碼。
之後出現了Unicode把所有語言都統一到一套編碼裡,這樣就不會再有亂碼問題了。但是,如果你寫的文本基本上全部是英文的話,用Unicode編碼比ASCII編碼需要多一倍的存儲空間,在存儲和傳輸上就十分不劃算。
是以又出現了把Unicode編碼轉化為“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字元根據不同的數字大小編碼成1-6個位元組,常用的英文字母被編碼成1個位元組,漢字通常是3個位元組,隻有很生僻的字元才會被編碼成4-6個位元組。如果你要傳輸的文本包含大量英文字元,用UTF-8編碼就能節省空間:
- 計算機記憶體中的運用:
在計算機記憶體中,統一使用Unicode編碼,當需要儲存到硬碟或者需要傳輸的時候,就轉換為UTF-8編碼。
用記事本編輯的時候,從檔案讀取的UTF-8字元被轉換為Unicode字元到記憶體裡,編輯完成後,儲存的時候再把Unicode轉換為UTF-8儲存到檔案.
浏覽網頁的時候,伺服器會把動态生成的Unicode内容轉換為UTF-8再傳輸到浏覽器:是以你看到很多網頁的源碼上會有類似的資訊,表示該網頁正是用的UTF-8編碼。
- python中字元串編碼:
在最新的Python 3版本中,字元串是以Unicode編碼的,也就是說,Python的字元串支援多語言
單個字元的編碼:
ord()函數擷取字元的整數表示chr()函數把編碼轉換為對應的字元
str和byte的互相轉換:
(為了避免亂碼問題,應當始終堅持使用UTF-8編碼對str和bytes進行轉換。):
str-> bytes (encode方法):
如果要在網絡上傳輸,或者儲存到磁盤上,就需要把str變為以位元組為機關的bytes。以Unicode表示的str通過encode()方法可以編碼為指定的bytes。
ASCII 隻能表示英文 ,UTF-8可以表示所有語言。 是以 'ABC'.encode('ascii') , '中文'.encode('utf-8') 都是對的,可是 '中文'.encode('ascii')就是錯的。
bytes -> str (decode方法):
如果我們從網絡或磁盤上讀取了位元組流,那麼讀到的資料就是bytes。要把bytes變為str,就需要用decode()方法:
如果bytes中包含無法解碼的位元組,decode()方法會報錯:
如果bytes中隻有一小部分無效的位元組,可以傳入errors='ignore'忽略錯誤的位元組。比如:
>>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')'中'
- 在python源檔案裡指定編碼
由于Python源代碼也是一個文本檔案,是以,當你的源代碼中包含中文的時候,在儲存源代碼時,就需要務必指定儲存為UTF-8編碼。
通常在檔案開頭寫上這兩行:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
第一行注釋是為了告訴Linux/OS X系統,這是一個Python可執行程式,Windows系統會忽略這個注釋;
第二行注釋是為了告訴Py
同時必須并且要確定文本編輯器正在使用UTF-8 without BOM編碼
(7):格式化:
- 用%運算符就是用來格式化字元串:
有幾個%?占位符,後面就跟幾個變量或者值,順序要對應好如果你不太确定應該用什麼,%s永遠起作用,它會把任何資料類型轉換為字元串:
>>> 'Age: %s. Gender: %s' % (25, True)
'Age: 25. Gender: True'有些時候,
字元串裡面的%是一個普通字元怎麼辦?這個時候就需要轉義,用%%來表示一個%:
>>> 'growth rate: %d %%' % 7'
growth rate: 7 %'
常見的占位符有:
占位符 | 替換内容 |
%d | 整數 |
%f | 浮點數 |
%s | 字元串 |
%x | 十六進制整數 |
- 使用字元串的format()方法格式化字元串
它會用傳入的參數依次替換字元串内的占位符{0}、{1}……,不過這種方式寫起來比%要麻煩得多
>>> 'Hello, {0}, 成績提升了 {1:.1f}%'.format('小明', 17.125)'
Hello, 小明, 成績提升了 17.1%'
3.4 布爾值:
-
- 用True、False表示布爾值(請注意大小寫)
- 布爾值可以用and、or和not運算
- 布爾值經常用在條件判斷中,比如:
if age >= 18:print('adult')else:print('teenager')
3.5 空值:
空值是Python裡一個特殊的值,用None表示。None不能了解為0,因為0是有意義的,而None是一個特殊的空值。Python還提供了清單、字典等多種資料類型,還允許建立自定義資料類型。
4.資料結構:
4.1清單list:
list是一種有序的集合,可以随時添加和删除其中的元素。
list 特征:
(1): list 裡面的元素的資料類型也可以不同
(2): list元素也可以是另一個list,此時list可以看成是一個二維數組,類似的還有三維、四維……數組
s = ['python', 'java', ['asp', 'php'], 'scheme']則s[2][1]就是指php
(3): list中一個元素也沒有,就是一個空的list,它的長度為0
(4): python中數組(list/array)不會複制,而是直接引用,此時要特别注意,如下圖,b = a,此時改變b就會改變a,是以有時候使用不當,會導緻某個變量莫名其妙就發生了變化。
對于單個變量,如:

将資料直接指派進行複制後,變量前後獨立,是位于兩塊空間内的。但對于數組(list 或 numpy.array):
相當于引用,是位于同一塊空間内的
(5):清單是python内置的可變序列,是包含若幹元素的有序連續記憶體區間,其元素資料類型可以各不相同。當清單增加或删除元素時,清單對象将自動進行記憶體的擴充或收縮,進而保證元素間沒有間隙。python清單記憶體的自動管理可以大幅減少程式員負擔,但是也可能造成清單内大量元素的移動,效率低。是以,除非必要,否則應該盡量從清單尾部進行元素的增删操作。
因為清單的指針使用的是連續記憶體空間存儲-元素不是,是以耗記憶體。
list可以進行的操作有:
(1):用len()函數可以獲得list元素的個數
(2):用索引來通路list中每一個位置的元素,記得索引是從0開始的。
比如classmates[0].
還可以用-1做索引,直接擷取最後一個元素。比如classmates[-1] 以此類推,可以擷取倒數第2個、倒數第3個。
當索引超出了範圍時,Python會報一個IndexError錯誤,是以,要確定索引不要越界,記得最後一個元素的索引是len(classmates) - 1
(3): 用append()函數往list中追加元素到末尾
(4):用insert()函數把元素插入到指定的位置。
比如 classmates.insert(1, 'Jack'),是指在索引為1的地方插入資料。
(5):用pop()方法删除list末尾的元素
要删除指定位置的元素,用pop(i)方法,其中i是索引位置
(6): 要把某個元素替換成别的元素,可以直接指派給對應的索引位置
>>> classmates[1] = 'Sarah'>>> classmates['Michael', 'Sarah', 'Tracy']
4.2 元組tuple:
tuple特征:
tuple和list非常類似,但是tuple一旦初始化就不能修改. 因為tuple不可變,是以代碼更安全。如果可能,能用tuple代替list就盡量用tuple。
tuple的定義用圓括号 (), list的定義用方括号[]
tuple操作:
(1):用len()函數可以獲得list元素的個數
(2):用索引來通路list中每一個位置的元素,記得索引是從0開始的。
tuple不能變,它也沒有append(),insert()這樣的方法。其他擷取元素的方法和list是一樣的,你可以正常地使用classmates[0],classmates[-1],但不能指派成另外的元素。
tuple的陷阱:
(1):定義隻有一個元素的tuple的時候,記得加上逗号。 因為括号()既可以表示tuple,又可以表示數學公式中的小括号,如果沒有逗号,則會認為是數學公式的小括号,計算結果自然是1。 比如:定義隻有一個元素1的tuple,應該是 t = (1,)
(2):tuple變成“可變”了:
比如下面的代碼,tuple裡面的list的值變了。其實 表面上看,tuple的元素确實變了,但其實變的不是tuple的元素,而是list的元素。tuple一開始指向的list并沒有改成别的list.
是以,tuple所謂的“不變”是說,tuple的每個元素,指向永遠不變。即指向'a',就不能改成指向'b',指向一個list,就不能改成指向其他對象,但指向的這個list本身是可變的!
>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t('a', 'b', ['X', 'Y'])
4.3 字典dict:
dict全稱dictionary,在其他語言中也稱為map,使用鍵-值(key-value)存儲,具有極快的查找速度。
表示:d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
dict特征:
(1):為什麼dict查找速度這麼快?因為dict的實作原理和查字典是一樣的。假設字典包含了1萬個漢字,我們要查某一個字,一個辦法是把字典從第一頁往後翻,直到找到我們想要的字為止,這種方法就是在list中查找元素的方法,list越大,查找越慢。
第二種方法是先在字典的索引表裡(比如部首表)查這個字對應的頁碼,然後直接翻到該頁,找到這個字。無論找哪個字,這種查找速度都非常快,不會随着字典大小的增加而變慢。dict就是第二種實作方式。
(2):由于一個key隻能對應一個value,是以,多次對一個key放入value,後面的值會把前面的值沖掉
(3):如果key不存在,dict就會報錯。
要避免key不存在的錯誤,有兩種辦法,
一是通過in判斷key是否存在
>>> 'Thomas' in dFalse
二是通過dict提供的get()方法,如果key不存在,可以傳回None,或者自己指定的value:
>>> d.get('Thomas')
>>> d.get('Thomas', -1)-1
(4): dict内部存放的順序和key放入的順序是沒有關系的
(5):dict的key必須是不可變對象, 這是因為dict根據key來計算value的存儲位置,如果每次計算相同的key得出的結果不同,那dict内部就完全混亂了。這個通過key計算位置的算法稱為雜湊演算法(Hash)。 要保證hash的正确性,作為key的對象就不能變。在Python中,字元串、整數等都是不可變的,是以,可以放心地作為key。而list是可變的,就不能作為key。
(6): 和list比較,dict有以下幾個特點:
1.查找和插入的速度極快,不會随着key的增加而變慢;
2.需要占用大量的記憶體,記憶體浪費多。
是以,dict是用空間來換取時間的一種方法。
dict操作:
(1): 用pop(key)方法删除一個key
(2): 根據key值查詢value值 比如: d['Michael']
(3): 用in方法判斷是否存在某個key
(4): 用get方法判斷是否存在某個key
4.4 集合set:
set和dict類似,也是一組key的集合,但不存儲value。
由于key不能重複,是以,在set中,沒有重複的key。
set特征:
(1):重複元素在set中自動被過濾
(2): set的原理和dict一樣,是以,同樣不可以放入可變對象,因為無法判斷兩個可變對象是否相等,也就無法保證set内部“不會有重複元素”。試試把list放入set就會報錯。
set操作:
(1): 通過add(key)方法可以添加元素到set中,可以重複添加,但不會有效果,因為set會自動過濾重複元素
(2): 通過remove(key)方法可以删除元素
(3): 兩個set可以做數學意義上的交集、并集等操作
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2{2, 3}
>>> s1 | s2{1, 2, 3, 4}
5.條件判斷
5.1 if語句的完整形式:
if :
elif :
elif :
else:
5.2 if判斷條件還可以簡寫:
if x: print('True')
隻要x是非零數值、非空字元串、非空list等,就判斷為True,否則為False。
5.3 有輸入的條件判斷:
用input()讀取使用者的輸入,然後進行判斷。
s = input('birth: ')
birth = int(s)
if birth < 2000:
print('00前')
else:
print('00後')
需要注意因為input()傳回的資料類型是str,str不能直接和整數比較,必須先把str轉換成整數
6.循環
6.1 for...in循環
依次把list或tuple中的每個元素疊代出來。比如:
sum = 0for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:sum = sum + xprint(sum)
6.2 while循環
隻要條件滿足,就不斷循環,條件不滿足時退出循環。比如:
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
3-4總結:
1.資料類型,資料結構彙總:
類型 | 特征 | 表示 | 操作 |
整數 | 正整數負整數 | 0xff00 ; 9 | |
浮點數 | 小數(正負) | 1.23 ; 1.23e9 | |
字元串 | 1.utf-8 編碼 2.格式化 %d 整數, %f浮點數, %s字元串, %x十六進制 format() | 1. 'abc' 2. 表示單引号 "'" 3. 轉義字元\ 'I\'m \"OK\"!' 4. 用r表示不轉義 print(r'\\\t\\') 5. 多行 print('''line1... line2... line3''') | |
布爾值 | True、False | ||
空值 | None | ||
list | 1.有序連續記憶體區間 2.元素的資料類型也可以不同 3.list元素也可以是另一個list 4.不會複制,而是直接引用,是以改變引用的變量的值會導緻原來的值變化 | a = [1,2,3] | 1.len()2.索引通路,指派3.append()4.insert()5.pop() |
tuple | tuple和list非常類似,但是tuple一旦初始化就不能修改 | t = (1,)t = (1,2,3) | 1.len() 2.索引通路 |
dict | 1.dict的key必須是不可變對象,而list是可變的,就不能作為key 2.使用鍵-值(key-value)存儲 | d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} | 1.用pop(key)方法删除一個ke y2.根據key值查詢value值 比如: d['Michael'] 3.用in方法判斷是否存在某個key : 'Thomas' in d 4.用get方法判斷是否存在某個key : d.get('Thomas') |
set | 1.set和dict類似,也是一組key的集合,但不存儲value 2.set不可以放入可變對象,list是可變對象,不能放入set3.set會自動過濾重複元素 | set([1, 2, 3]) | 1.通過add(key)方法可以添加元素到set中 2.通過remove(key)方法可以删除元素 3.兩個set可以做數學意義上的交集、并集等操作 |
2.不可變對象
str是不變對象,而list是可變對象可變對象:
對于可變對象,比如list,對list進行操作,list内部的内容是會變化的,
比如:
>>> a = ['c', 'b', 'a']
>>> a.sort()
>>> a['a', 'b', 'c']
不可變對象,比如str,對str進行操作後,str内部的内容不會變化,比如:
>>> a = 'abc'
>>> b = a.replace('a', 'A')
>>> b'Abc'
>>> a'abc'
a是一個變量,它指向的内容是‘abc’,當我們調用replace方法的時候,作用是在字元串對象‘abc’上,replace方法建立了一個新字元串‘Abc’并傳回變量b指向這個新的字元串。是以,對于不變對象來說,調用對象自身的任意方法,也不會改變該對象自身的内容。相反,這些方法會建立新的對象并傳回,這樣,就保證了不可變對象本身永遠是不可變的。