Python程序能夠分解爲模塊、語句、表達式以及對象,以下所示:html
程序由模塊構成python
模塊包含語句git
語句包含表達式程序員
表達式創建並出口對象算法
1、Python類型的介紹:數據庫
1.1 爲何使用內置類型編程
Python提供了強大的對象類型做爲語言的組成部分,事實上,除非有內置類型沒法提供的特殊對象要處理,最好老是使用內置對象而不是使用本身的實現。下面是其緣由:api
內置對象使程序更容易編寫:數組
對於簡單的任務,內置類型每每可以表現問題領域的全部結構。例如,集合(列表)和搜索表(字典)能夠立刻使用它們,僅使用python內置對象類型就能完成不少工做。網絡
內置對象使擴展的組建:
對於較爲複雜的任務,或許仍須要提供本身的對象,使用python的類或C語言的結構。例如,堆棧數據結構也許會實現爲管理和定製內置列表的類。
內置對象每每比定製的數據結構更有效率:
在速度方面,python內置類型優化了用C實現數據結構算法。儘管能夠實現屬於本身的相似的數據類型,但每每很難達到內置數據類型所提供的性能水平。
內置對象是語言的標準的一部分:
python不但借鑑了依靠內置工具的語言(例如LISP),並且吸收了那些依靠程序員去提供本身實現的工具或框架的語言(例如C++)的優勢。儘管在Python中能夠實現獨一無二的對象類型,但在開始階段並無必要這樣作。此外,由於Python的內置工具是標準的,他們通常都是一致的。
1.2 Python的核心數據類型
python的內置對象類型和一些編寫其常量(literal)所使用到的語法,也就是可以生成這些對象的表達式。
內置對象:
數字、字符串、列表、字典、元組、文件、集合、其餘類型、編程單元類型、與實現相關的類型
上面所列內容並不完整,由於在python程序中處理的每樣東西都是一種對象。例如,在python中進行文本模式匹配時,建立了模式對象,還有進行網絡腳本編程時,使用了套接字對象,它們由def、class、import和lamba這樣的語句和表達式建立,而且能夠在腳本間自由地傳遞,存儲在其餘對象中等。
1.3數字
python的核心對象集合包括常規的類型:整數、浮點數以及更爲少見的類型(有虛部的複數、固定精度的十進制數、帶分子和分母的有理分數以及集合等)。
python的基本數字類型仍是至關基本的。python中數字支持通常的數學運算。其中**表示乘方。
>>> 12+33 45 >>> 1.5*4 6.0 >>> 2 ** 100 1267650600228229401496703205376
#注意這裏的最後一個記過:當須要的時候,python 3.0的整數類型會自動提供額外的精度,以用於較大的數值。
1.4 字符串
就像任意字符的集合同樣,字符串是用來記錄文本信息的。從嚴格意義上來講,字符串是單個字符的字符串的序列,其餘類型的序列還包括列表和元組。
做爲序列,字符串支持假設其中各個元素包含位置順序的操做。例如,若是咱們有四個字符的字符串,咱們經過內置的len函數驗證其長度並索引操做獲得其各個元素。
>>> S = 'Spam' >>> len(S) 4 >>> S[0] 'S' >>> S[1] 'p'
在Python中,索引是按照最前面的偏移量進行編碼的,也就是從0開始,第一項索引爲0,第二項索引爲1,以此類推。
>>> S[-1] 'm' >>> S[-2] 'a' >>>
#在Python中,咱們可以反向索引,從最後一個開始(反向索引是從左邊開始計算,反向索引是從右邊開始計算)
>>> S[len(S)-1] 'm'
#通常來講,負的索引號會簡單地與字符串的長度相加,所以,上面操做和S[-1]是等效的。
>>> S[1:3] 'pa'
#除了簡單的從位置進行索引,序列也支持一種所謂分片(slice)的操做,這是一種一步就可以提取整個分片(splice)的方法。
>>> S[1:] 'pam' >>> S[0:3] 'Spa' >>> S[:3] 'Spa' >>> S[:-1] 'Spa' >>> S[:] 'Spam'
#在一個分片中,左邊界默認爲0,而且右邊界默認爲分片序列的長度。
>>> S+'xyz' 'Spamxyz' >>> S*8 'SpamSpamSpamSpamSpamSpamSpamSpam'
#做爲一個序列,字符串也支持使用加號進行合併(將兩個字符串合成爲一個新的字符串),或者重複(經過再重複一次建立一個新的字符串)。
#注意加號(+)對於不一樣的對象有不一樣的意義:對於數字爲加法,對於字符串爲合併。這是Python的通常特性,也就是咱們將會在本書後面提到的多態。簡而言之,一個操做的意義取決於被操做的對象。Python編寫的操做一般自動地適用於不一樣類型的對象。
#同時字符串還具備不可變性。如上面的例子
>>> S.find('pa') 1 >>> S.find('pd') -1 >>> S.replace('pa','XYZ') 'SXYZm' >>> S 'Spam'
#字符串的find方法是一個基本的字符串查找的操做(它將返回一個傳入字符串的偏移量,或者沒有找到的狀況下返回-1),而字符串的replace方法將會對全局進行搜索和替換。
#儘管這些字符串方法的命名有改變的含義,但在這裏咱們都不會改變原始的字符串,而是會建立一個新的字符串做爲結果------由於字符串具備不可變性。
>>> line='aaa,bbb,ccccc,dd' >>> line.split(',')#以逗號爲分隔符對字符串進行切片
['aaa', 'bbb', 'ccccc', 'dd'] >>> S='spam' >>> S.upper()#將小寫轉換成大寫
'SPAM' >>> S.isalpha()#檢測是不是字母組成,布爾值,不是的話返回false。
True >>> line='aaa,bbb,ccccc,dd\n' >>> line=line.rstrip()#去掉兩邊的空格
>>> line 'aaa,bbb,ccccc,dd'
#還能實現經過分隔符將字符串拆分爲子字符串(做爲一種解析的簡單形式),大小寫變換,測試字符串的內容(數字、字母或其餘),去掉字符串後的空格字符。
>>> 'name:%s,age:%s' %('chaishao','27')#這種就相似於位置參數,按位置將值傳給前面的%s
'name:chaishao,age:27' >>> 'chaishao:{1},age:{0}'.format(27,'chaishao')#這種仍是定義位置,前面{1}和{0}表示要第二個位置的值和第一個位置的值
'chaishao:chaishao,age:27' >>> 'chaishao:{name},age:{age}'.format(name='chaishao',age=27)#這種就是前面定義變量,後面給變量賦值
'chaishao:chaishao,age:27'
#字符串還支持一個叫作格式化的高級替代操做,能夠以一個表達式的形式和一個字符串方法調用。如上面的例子.
>>> dir(S) ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '_ _le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'iss pace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'sw apcase', 'title', 'translate', 'upper', 'zfill']
#對於更多的細節,能夠經過調用內置的dir函數,將會返回一個列表,其中包含了對象的全部屬性。因爲方法是函數屬性,他們也會在這個列表中出現。上面那些變量名中有下劃線的內容,它們表明了字符串對象的實現方式,並支持定製。通常來講,以雙下劃線開頭並結尾的變量名是用來表示Python實現細節的命名模式。而這個列表中沒有下劃線的屬性是字符串對象可以調用的方法。
>>> help(S.replace) Help on built-in function replace: replace(...) method of builtins.str instance S.replace(old, new[, count]) -> str Return a copy of S with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced.
#dir函數簡單地給出了方法的名稱。要查詢它們是作什麼的,能夠將其傳遞給help函數。就像PyDoc同樣(一個從對象中提取文檔的工具),help是一個隨Python一塊兒分發的面向系統代碼的接口。
>>> help(S) No Python documentation found for 'spam'. Use help() to get the interactive help utility. Use help(str) for help on the str class. >>> help(str)#能夠查看str的全部help幫助說明
Help on class str in module builtins:
#如上面能夠直接查看全部的幫助說明就像查看man幫助同樣,不過通常仍是針對某個特定的方法進行查看。
>>> S='A\nB\tC' >>> len(S)#查看字符串的長度
5 >>> ord('\n')#ord() 函數是 chr() 函數(對於8位的ASCII字符串)或 unichr() 函數(對於Unicode對象)的配對函數,它以一個字符(長度爲1的字符串)做爲參數,返回對應的 ASCII 數值,或者 Unicode 數值,若是所給的 Unicode 字符超出了你的 Python 定義範圍,則會引起一個 TypeError 的異常。
10 >>> S='A\0B\0C' >>> len(S) 5
#上面的反斜線轉義序列表示特殊的字符。
>>> msg=""" abc ... def'''ABC""BCD'HAHA""" >>> msg ' abc\ndef\'\'\'ABC""BCD\'HAHA' >>> print(msg) abc def'''ABC""BCD'HAHA
#Python容許字符串包括在單引號或雙引號中(他們表明着相同的東西)。它也容許在三個引號(單引號或雙引號)中包括多行字符串常量。當採用這種形式的時候,全部的行都合併在一塊兒,並在每一行的末尾增長換行符。在Python腳本中嵌入像HTML或XML這樣的內容時,是很方便的。
1.5 列表
Python的列表對象是這個語言提供的最通用的序列。列表是一個任意類型的對象的位置相關的有序集合,它沒有固定的大小。不像字符串,其大小是可變的,經過對偏移量進行賦值以及其餘各類列表的方法進行調用,確實可以修改列表的大小。
>>> L=[123,'spam',1.23] >>> len(L) 3 >>> L[0]#查看列表的索引,下標從0開始。
123 >>> L[:-1]#也能夠對列表進行分片,這裏就是[0:2]
[123, 'spam'] >>> L + [4,5,6]#兩個列表能夠合併
[123, 'spam', 1.23, 4, 5, 6] >>> L [123, 'spam', 1.23]
#因爲列表是序列的一種,列表支持全部的咱們隊字符串所討論過得序列操做。惟一的區別就是其結果每每是列表而不是字符串。
#列表和其餘語言中的數組有些相似,可是列表要強大不少,其中一點就是列表沒有固定類型的約束。例如,上面的列表就包含了三個徹底不一樣類型的對象(一個整數、一個字符串、以及一個浮點數)。此外,列表沒有固定大小,也就是說可以按照須要增長或減小列表大小,來響應其特定的操做。
>>> L.append('NI') #在列表尾部添加一個NI >>> L [123, 'spam', 1.23, 'NI'] >>> L.pop(2) #刪除索引2也就是從左往右第三個元素 1.23 >>> L [123, 'spam', 'NI']
>>> L.insert(1,'haha') #在索引1的位置插入haha對象
>>> L
[123, 'haha', 'spam', 'NI']
>>> L.remove(123) #刪除123
>>> L
['haha', 'spam', 'NI']
#列表的append方法擴充了列表的大小並在列表的尾部插入一項;pop方法(或者等效的del語句)移除給定偏移量的一項,從而讓列表減少。其餘的列表方法能夠在任意位置插入(insert)元素,按照值移除(remove)元素等。由於列表是可變的,大多數列表的方法都會就地改變列表對象,而不是建立一個新的列表。
>>> list1=['bb','aa','cc'] >>> list1.sort() #對列表進行排序默認是按照升序排序
>>> list1 ['aa', 'bb', 'cc'] >>> list1.reverse()#對列表進行翻轉
>>> list1 ['cc', 'bb', 'aa']
#列表sort方法是對列表排序的意思,這些方法都會直接對列表進行改變。
>>> list1[1] #查找list1列表偏移量是1也就是第二個元素 'bb' >>> list1[3] #超出邊界直接會報錯 Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
>>> list1[1]='BB' #對列表第二個元素從新賦值
>>> list1[3]='CC' #超出列表末尾範圍以外賦值會報錯
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
>>> list1
['cc', 'BB', 'aa']
#儘管列表沒有固定的大小,Python扔不容許引用不存在的元素。超出列表末尾以外的索引老是會致使錯誤,對列表末尾範圍以外賦值也是如此。這是有意而爲之的,因爲去給一個列表邊界外的元素賦值,每每會獲得一個錯誤(而在C語言中狀況比較糟糕,由於它不會像Python這樣進行錯誤檢查)。在Python中,並非默默的增大列表做爲響應,而是會提示錯誤。爲了讓一個列表增大,能夠調用相似於append這樣的列表方法。
>>> M=[[1,2,3],[4,5,6],[7,8,9]] >>> M [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> M[1] #獲取第二個元素的值
[4, 5, 6]
>>> M[1][2] #獲取第二個元素裏面嵌套的列表的第三個元素的值
6
#Python核心數據類型的一個優秀的特性就是他們支持任意的嵌套。可以以任意的組合對其進行嵌套,並能夠多個層次進行嵌套(例如,可以讓一個列表包含一個字典,並在這個字典中包含另外一個列表等)。這種特性的一個直接的應用就是實現矩陣,或者Python中的「多維數組」,一個嵌套列表的列表就能完成這個基本的操做。上面咱們編寫了一個包含3個其餘列表的列表。其效果就是表現了一個3*3的數字矩陣。
>>> col2 = [row for row in M] #for row in M是一個for循環,那麼row久表明了M裏面的三個元素,因此col2的值就是M的值
>>> col2 [[1, 2, 3], [4, 5, 6], [7, 8, 9]] >>> col2=[row[1] for row in M] #這裏row[1]就至關於取M[1]
>>> col2 [2, 5, 8]
#列表解析,處理序列的操做和列表的方法中,Python還包括了一個更高級的操做,成爲列表解析表達式,從而提供了一個處理像矩陣這樣結構的強大工具。列表解析源自集合的概念。它是一種經過對序列中的每一項運行一個表達式來建立一個新列表的方法,每次一個,從左至右。列表解析是編寫在方括號中的,而且由使用了同一個變量名的(這裏是row)表達式和循環結構組成。上面的這個列表解析表達基本上就是它字面上所講的,把矩陣M的每一個row中的row[1]放到一個新的列表中。
>>> col2 [2, 5, 8] >>> [row[1]+1 for row in M] #把它蒐集到的每個元素都加1
[3, 6, 9] >>> [row[1] for row in M if row[1] % 2 == 0] #使用if條件語句,經過使用%求餘表達式(取餘數)過濾告終果中的奇數。
[2, 8]
>>> M
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> diag = [M[i][i] for i in [0,1,2]] #M[i][i]就至關於M[0][0],M[1][1],M[2][2]
>>> diag
[1, 5, 9]
>>> doubles = [c*2 for c in 'spam'] #取出來的值*2
>>> doubles
['ss', 'pp', 'aa', 'mm']
>>> G = (sum(row) for row in M) #讓row求和,由於是for循環嘛,這裏的意思就至關於讓M[0],M[1],M[2]分別求和
>>> next(G) #next() 返回迭代器的下一個項目
6
>>> next(G)
15
>>> next(G)
24
>>> list(map(sum,M)) #內置map能夠作上面相似的事情,產生對各項運行一個函數的結果,在Python 3.0中,將其包裝到列表中,會使其返回全部值。
[6, 15, 24]
>>> {sum(row) for row in M} #能夠用解析語法來建立一個集合
{24, 6, 15}
>>> {i : sum(M[i]) for i in range(len(M))} #能夠用解析語法來建立一個字典
{0: 6, 1: 15, 2: 24}
#實際應用中的列表解析能夠更復雜,如上面。列表解析建立了新的列表做爲結果,可是可以在任何可迭代的對象上進行迭代。
#列表解析以及相關的內容函數map和filter比較複雜,這裏記錄一下先。實際上,在python 3.0中,列表、集合和字典均可以用解析來建立。
1.6 字典
Python中的字典是徹底不一樣的東西:它們不是序列,而是一種映射(mapping)。映射是一個其餘對象的集合,可是它們是經過鍵而不是相對位置來存儲的。實際上,映射並無任何可靠的從左至右的順序。它們簡單地將鍵映射到值。字典是Python核心對象集合中的惟一的一種映射類型,也具備可變性------能夠就地改變,並能夠隨需求增大或減少、就像列表那樣。
>>> D={'food':'Spam','quantity':4,'color':'pink'}#定義一個字典D
>>> D['food']#字典food鍵的值
'Spam' >>> D['quantity'] += 1#字典quantity的值加1
>>> D {'color': 'pink', 'food': 'Spam', 'quantity': 5}
#上面是映射操做,做爲常量編寫時候,字典編寫在大括號中,幷包含一系列的「鍵:值」對。在咱們須要將鍵與一系列值相關聯(例如,爲了表述某物的某屬性)的時候,字典是頗有用的。上面的例子是一個包含了三個元素的字典(鍵分別爲「food」、「quantity」和「color」)。經過鍵對字典進行索引來讀取或改變鍵所關聯的值。字典的索引操做使用的是和序列相同的語法,可是在方括號中的元素是鍵,而不是相對位置。上面就是使用大括號這種常量形式。
>>> D={}#先定義一個空字典
>>> D['name']='chaishao'#經過給這種定義鍵值對的形式直接給字典賦值
>>> D['job']='dev' >>> D['age']=27 >>> D {'age': 27, 'name': 'chaishao', 'job': 'dev'} >>> print(D['name']) chaishao
#上面就是一種建立空字典,而後每次以一個鍵來填寫它的方式。與列表中禁止邊界外的賦值不一樣,對一個新的字典的鍵賦值會建立該鍵。
#上面最後一個例子,實際是使用字典的鍵來搜索對應的值,在別的應用中,字典能夠用來執行搜索,經過鍵索引一個字典每每是Python中編寫搜索的最快方法。
>>> rec = {'name':{'first':'chai','last':'shao'},#記錄了姓和名,這就屬於字典嵌套字典
... 'job':['dev','mgr'],#記錄了職位和角色,這就是嵌套了列表
... 'age':27}
>>> rec
{'age': 27, 'name': {'last': 'shao', 'first': 'chai'}, 'job': ['dev', 'mgr']}
>>> rec['name'] #查找字典rec關於name鍵的值
{'last': 'shao', 'first': 'chai'}
>>> rec['name']['last'] #查找字典rec關於name鍵中的last鍵的值
'shao'
>>> rec['job']
['dev', 'mgr']
>>> rec['job'][-1]#查找rec字典中job鍵中列表最後一個元素的值
'mgr'
>>> rec['job'].append('CTO') #給rec字典中的job鍵中的列表加入一個CTO的值
>>> rec
{'age': 27, 'name': {'last': 'shao', 'first': 'chai'}, 'job': ['dev', 'mgr', 'CTO']}
#上面在頂層使用了三個鍵的字典(鍵分別是「name」、「job」和「age」),可是值的狀況變得複雜得多:一個嵌套的字典做爲name的值,支持了多個部分,並用一個嵌套的列表做爲job的值從而支持多個角色和將來的擴展。可以獲取這個結構的組件,就像以前在矩陣中所做的那樣,可是此次索引的是字典的鍵,而不是列表的偏移量。
#注意這裏的最後一個操做是如何擴展嵌入job列表的。由於job列表是字典所包含的一部分獨立的內存,它能夠自由的增長和減小。
>>> rec=0 >>> rec 0
#在Python中,當最後一次引用對象後(例如,將這個變量用其餘的值進行賦值),這個對象所佔用的內存空間將會自動清理掉,相似於上面那種。從技術上來講,Python具備一種叫作垃圾收集的特性,在程序運行時能夠清理再也不使用的內存,並將你從必須管理代碼中這樣的細節中解放出來。在Python中,一旦一個對象的最後一次引用被移除,空間將會當即回收。
>>> D = {'a':1,'d':2,'c':3} >>> Ks = list(D.keys()) #將字典D的鍵作成列表賦值給Ks
>>> Ks
['a', 'd', 'c'] >>> Ks.sort() #進行一下排序
>>> Ks ['a', 'c', 'd'] >>> D = {'a':1,'c':2,'b':3} >>> D ##字典不是序列,它們並不包含任何可靠的從左至右的順序,這意味着若是咱們創建一個字典,並將它打印出來,它的鍵也許會以與咱們輸入時不一樣的順序出現。
{'a': 1, 'b': 3, 'c': 2} >>> Ks = list(D.keys())
>>> Ks.sort()
>>> for key in Ks: #寫個for循環
... print(key,'=>',D[key]) #循環打印key的名稱和D字典裏key的值
... #按一次回車是繼續寫,咱們要出結果因此須要按兩次回車
a => 1 b => 3 c => 2
#上面的例子若是一個字典的元素中,須要強調鍵的某種順序的話,經常使用的解決辦法就是經過字典的keys方法收集一個鍵的列表,而後使用列表的sort方法進行排序,而後使用Python的for循環逐個進行顯示結果。
>>> for key in sorted(D): ... print(key,'=>',D[key])#注意這裏,要按個空格再打print啊,否則按回車要報錯的。
... a => 1 c => 3 d => 2
#經過使用最新的sorted內置函數就能夠一步完成上面對key的排序。sorted調用返回結果並對各類對象類型進行排序,上面的例子就是自動對字典的鍵排序。
>>> squares = [x ** 2 for x in [1,2,3,4,5]] >>> squares [1, 4, 9, 16, 25] >>> squares1=[] >>> for x in [1,2,3,4,5]:#編寫了一個等效的for循環,經過在運行時手動增長列表來建立最終的列表。
... squares1.append(x ** 2) ... >>> squares [1, 4, 9, 16, 25]
#迭代和優化,for循環是真正經過的迭代工具。事實上,它們都可以工做於遵照迭代協議(這是Python中無處不在的一個概念,表示在內存中物理存儲的序列,或一個在迭代操做狀況下每次產生一個元素的概念,表示在內存中物理存儲的序列,或一個在迭代操做狀況下每次產生一個元素的對象)的任意對象。若是一個對象在響應next以前先用一個對象對iter內置函數作出響應,那麼它屬於後一種狀況。咱們在前面所見到生成器解析表達式就是這樣的一個對象。
#從左到右掃描一個對象的每一個Python工具都使用迭代協議。這就是上上個例子介紹的sorted調用直接工做於字典之上,咱們沒必要調用keys方法來獲得一個序列,由於字典是可迭代的對象,能夠用一個next返回後續的鍵。這也就一意味着像上面任何列表解析表達式均可以計算一列數字的平方。
#儘管這樣,列表解析和相關的函數編程工具,如map和filter,一般運行得比for循環快:這是對有大數據集合的程序有重大影響的特性之一。在Python中性能測試是一個很難應付的任務,由於它在反覆地優化。
#Python中的一個主要原則就是,首先爲了簡單和可讀性去編寫代碼,在程序能夠工做,並證實了確實有必要考慮性能後,再考慮該問題。更多的狀況是代碼自己就已經足夠快了。若是確實須要提升代碼的性能,那麼Python提供了幫助你實現的工具,包括time以及timeit模塊和profile模塊。
>>> D {'a': 1, 'd': 2, 'c': 3} >>> D['e'] = 99 #雖然可以經過給新的鍵值來擴展字典
>>> D {'a': 1, 'e': 99, 'd': 2, 'c': 3} >>> D['f'] #可是獲取一個不存在的鍵值仍然是一個錯誤
Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'f' >>> 'f' in D #編寫程序時並非老是知道當前存在什麼鍵,能夠經過in關係表達式,來查詢字典中的一個鍵是否存在。
False >>> if not 'f' in D: #也能夠經過使用Python的If語句對結果進行分支處理
... print('missing') ... missing
>>> value = D.get('x',0) #這是另一種方法,若是獲取鍵失敗就給賦值0
>>> value
0
>>> value = D['f'] if 'f' in D else 0 #這是跟if結合,若是f鍵存在就將f的值賦給value,不然賦值0
>>> value
0
#默認狀況下,if語句也能夠有else分句,以及一個或多個elif(else if)分句進行其餘的測試。它是Python主要的選擇工具,而且是腳本中編寫邏輯的方法。
1.7 元組
元組對象(tuple)基本上就像一個不能夠改變的列表。就像列表同樣,元組是序列,可是它具備不可變性,和字符串相似。從語法上講,它們編寫在圓括號中而不是方括號中,它們支持任意類型、任意嵌套以及常見的序列操做。
>>> T = (1,2,3,4) #定義一個元組
>>> len(T) 4 >>> T + (5,6) #兩個元組合並
(1, 2, 3, 4, 5, 6) >>> T[1] #查找元組偏移量是1的也就是第二個元素
2 >>> T.index(4) #查找元素4所在的索引位置
3 >>> T.count(4) #查找4這個元素在元組中出現的次數
1 >>> T[0] = 2 #元組是不可變的,若是想改變元組的值直接就報錯了
Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment
#上面就是元組的經常使用操做以及不可變的演示。
>>> T = ('spam',3.0,[1,2,3]) #元組也支持混合的類型和嵌套
>>> T[1] #查找偏移量是1的值
3.0 >>> T[2][2] #查找偏移2也就是最後的列表中的第三個元素
3 >>> T.append(4) #元素不能增加或縮短,由於它們是不可變的
Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'tuple' object has no attribute 'append'
#爲何要用元組呢,它的關鍵是不可變性。若是在程序中以列表的形式傳遞一個對象的集合,它可能在任何地方改變;若是使用元組的話,則不能。
1.8 文件
文件對象是Python代碼對電腦上外部文件的主要接口。雖然文件是核心類型,可是它有些特殊:沒有特定的常量語法建立文件。要建立一個文件對象,需調用內置的open函數以字符串的形式傳遞給它一個外部的文件名以及一個處理模式的字符串。
>>> f = open('data.txt','w') #以寫的方式打開文件
>>> f.write('Hello\n') #寫入Hello並換行
6 >>> f.write('world\n') #寫入world並換行
6 >>> f.close() #關閉文件,就會把寫的內容寫入到文件
#例如上面,建立一個文本輸出文件,能夠傳遞其文件名以及‘w’處理模式字符串以寫數據,這樣就在當前文件夾下建立了一個文件,並向它寫入文本(文件名能夠是完整的路徑)。
>>> f=open('data.txt') >>> text = f.read() >>> text 'HelloHello\nworld\n' >>> print(text) HelloHello world >>> text.split() ['HelloHello', 'world']
#上面的例子是打開文件,默認就是r類型,而後將文件的內容讀至一個字符串,並顯示它。對腳本而言,文件的內容老是字符串,不管文件包含的數據是什麼類型。
#文化提供了多種讀和寫的方法(read能夠接受一個字節大小的選項,readline每次讀一行等),以及其餘的工具(seek移動到一個新的文件位置)。讀取一個文件的最佳方式就是根本不讀它,文件提供了一個迭代器(iterator),它在for循環或其餘環境中自動地一行一行地讀取。
#其餘文件類工具:open函數可以實如今Python中編寫的絕大多數文件處理。儘管這樣,對於更高級的任務,Python還有額外的類文件工具:管道、先進先出隊列(FIFO)、套接字、經過鍵訪問文件、對象持久、基於描述符的文件、關係數據庫和麪向對象數據庫接口等。例如,描述符文件(descriptor file)支持文件鎖定和其餘的底層工具,而套接字提供網絡和進程間通訊的接口。
1.9 其餘核心類型
集合,它不是映射也不是序列,相反,它是惟一的不可變的對象的無序集合。集合能夠經過調用內置set函數而建立,或者使用Python 3.0中新的集合常量和表達式建立,而且它支持通常的數學集合操做。
http://www.cnblogs.com/chaishao/p/5759436.html #開頭部分對集合的介紹和文件的介紹。
2、數字
2.1 數字類型介紹
Python的數字類型是至關典型的,在Python中,數字並非一個真正的對象類型,而是一組相似類型的分類。Python不只支持一般的數字類型(整數和浮點數),並且可以經過常量直接建立數字以及處理數字的表達式。此外,Python爲更高級的工做提供了不少高級數字編程支持和對象。Python數字類型的完整工具包括:
整形和浮點數、複數、固定精度的十進制數、有理分數、集合、布爾類型、無窮的整數精度、各類數字內置函數和模塊。
數字常量:在基本類型中,Python提供了:整數(正整數和負整數)和浮點數(帶小數部分的數字)。Python還容許咱們使用十六進制、八進制常量來表示整數,提供一個複數類型,而且容許整數具備無窮的精度(只要內存空間容許,它能夠增加成任意位數的數字)。下面展現了Python數字類型在程序中的顯示方式(做爲常量):
#通常來講,Python的數字類型是很容易使用的,除了內置數字常量以外,Python還提供了一系列處理數字對象的工具:
表達式操做符:+、-、*、\、>>、**、&等
內置數學函數:pow、abs、round、int、hex、bin等
公用模塊:random、math等
2.2 Python表達式操做符
表達式式處理數字的最基本的工具。當一個數字(或其餘對象)與操做符想結合時,Python執行時將計算獲得一個值。在Python中,表達式式使用一般的數學符號和操做符號寫出來的。除了經常使用的是加減乘數,%是計算餘數操做符、<<執行左移位、&計算位與的結果等。其餘的則更Python化一些,而且不全都具有數值特徵。例如,is操做符測試對象身份(也就是內存地址,嚴格意義上的相等),lambda建立匿名函數。
Python表達式操做符及程序:
下面是Python2.6和Python3中操做符的版本差別和最新添加:
1. 在python 2.6版中,值不相等能夠寫成X != Y或X <> Y.在python 3.0之中,後者會被移除,由於它是多餘的。值不相等測試使用X != Y就好了。
2. 在Python 2.6中,一個後引號表達式‘X’和repr(X)的做用相同,轉換對象以顯示字符串。因爲其很差理解,Python 3.0刪除了這個表達式,使用更容易理解的str和repr內置函數。
3. 在Python 2.6和Python 3.0中,floor除法表達式(X // Y)老是會把餘數小數部分去掉。在Python 3.0中,X / Y表達式執行真正的除法(保留餘數)和Python 2.6中的傳統除法(截除爲整數)。
4. 列表語法([...])用於表示列表常量或列表解析表達式。後者是執行隱形循環,把表達式的結果收集到新的列表中。
5. (...)語法用於表示雲組和表達式,以及生成器表達式,後者是產生所需結果的列表解析的一種形式,而不是構建一個最終的列表。
6. {...}語法表示字典常量,而且在Python 3.0中能夠表示集合常量以及字典和集合解析。
7. yield和三元選擇表達式和Python 2.5及其之後的版本中可用。前者返回生成器中的send(...)參數,後者是一個多行if語句的縮寫形式。若是yield不是單獨地位於一條賦值語句的右邊的話,須要用圓括號。
8. 比較操做符能夠連續使用:X <Y <z的結果與X < Y < X相同。
9. 在最近的Python中,分片表達式X[I:J:K]等同於同一個分片對象索引:X[slice(I,J,K)]。
10. 在Python 3.0中,對字典的大小比較也再也不支持(儘管支持相等性測試);比較sorted(dict.items())是一種可能的替代。
2.3 十六進制、八進制和二進制記數
Python證書可以以十六進制、八進制和二進制記數法來編寫,做爲通常的以10位基數的十進制記數法的補充。這些常量只是指定一個整數對象的值的一種替代方法,例如,Python 3.0和Python 2.6中的以下常量編碼會產生具備3種進制的指定值的常規整數:
>>> 0o1,0o20,0o377 #八進制
(1, 16, 255) >>> 0x01,0x10,0xFF #十六進制
(1, 16, 255) >>> 0b1,0b100000,0b111111111 #二進制
(1, 32, 511) >>> 0b1,0b10000,0b111111111 (1, 16, 511) #都表示十進制的數
>>> oct(255),hex(255),bin(255) #將十進制數字轉變成對應的進制數
('0o377', '0xff', '0b11111111')
>>> int('255'),int('377',8),int('ff',16),int('11111111',2)
(255, 255, 255, 255)
>>> int('255'),int('0o377',8),int('0xff',16),int('0b11111111',2)
(255, 255, 255, 255)
#oct函數會將十進制數轉換爲八進制數,hex函數會將十進制轉換爲十六進制數、而bin會將十進制數轉換爲二進制。另外一種方式,內置的Int函數會將一個數字的字符串變換爲一個整數,並能夠經過定義的第二個參數來肯定變換後的數字的進制。
2.4 位操做
除了通常的數學運算(加法、減法等),Python也支持C語言中大多數數學表達式。這包括哪些把整數當作二進制位串對待的操做。
>>> x = 1 #換算成二進制這就至關於0001
>>> x << 2 #二進制逢2進位,0001左移動兩位,變成了0100,就表示十進制的4了
4 >>> x | 2 #這是二進制的或運算,前面的是0001後面的是0010,因此就是0001|0010=0011,換算成十進制就是3了
3 >>> x & 1 #這個就是與的關係,就是0001&0001=0001,也就是1
1
>>> x & 2 #這個就是0001&0010=0000,也就是0
0
#像上面這樣按位進行掩碼的運算,使咱們能夠對一個整數進行多個標誌位和值進行編碼。在這個領域裏,Python 2.6 和Python 3.0中都支持的二進制和十六進制變得特別有用,它們容許咱們按照位字符串來編寫和查看數字。若是Python代碼必須與由C程序生成的網絡包或封裝了的二進制數打交道的話,它是很實用的。儘管這樣,注意位操做在Python這樣的高級語言中並不像在C這樣的底層語言中那麼重要。
2.5 其餘的內置數學工具
除了核心對象類型之外,Python還支持用於數字處理的內置函數和內置模塊。例如,內置函數pow和abs,分別計算冪和絕對值,這裏有一些內置match模塊(包含在C語言中math庫中的絕大多數工具)的例子並有一些實際中的內置函數。
>>> import math >>> math.pi,math.e (3.141592653589793, 2.718281828459045) >>> math.sin(2 * math.pi / 180) 0.03489949670250097 >>> math.sqrt(144),math.sqrt(2) (12.0, 1.4142135623730951) >>> pow(2,4),2 ** 4 (16, 16) >>> abs(-42.0),sum((1,2,3,4)) (42.0, 10) >>> min(3,1,2,4),max(3,1,2,4) (1, 4)
>>> math.floor(2.567),math.floor(-2.567)
(2, -3)
>>> math.trunc(2.567),math.trunc(-2.567)
(2, -2)
>>> int(2.567),int(-2.567)
(2, -2)
>>> round(2.567),round(2.467),round(2.567,2)
(3, 2, 2.57)
>>> (1/3),round(1/3),('%.2f'%(1/3))
(0.3333333333333333, 0, '0.33')
>>> (1/3),round(1/3,2),('%.2f'%(1/3))
(0.3333333333333333, 0.33, '0.33')
>>> '%.1f' % 2.567, '{0:.2f}'.format(2.567)
('2.6', '2.57')
#這裏展現的的sum函數做用於數字的一個序列,min和max函數接受一個參數序列或者單個的參數。有各類各樣的方法能夠刪除一個浮點數的小數位。
#上線也介紹了截斷和floor方法,也能夠用round,無論是爲了求值仍是爲了顯示。
#最後一個例子產生了咱們一般會打印出的字符串,而且它支持各類格式化選項。
>>> import math >>> math.sqrt(144) 12.0 >>> 144 ** .5 12.0 >>> pow(144, .5) 12.0 >>> math.sqrt(1234567890) 35136.41828644462 >>> 1234567890 ** .5 35136.41828644462 >>> pow(1234567890, .5) 35136.41828644462
#在Python中有3種方法能夠計算平方根:使用一個模塊函數、一個表達式或者一個內置函數。注意內置math這樣的模塊必須先導入,可是abs這樣的內置函數不須要導入就能夠直接使用,換句話說,模塊是外部的組件,而內置函數位於一個隱性的命名空間內,Python自動搜索程序的變量名。這個命名空間對應於Python 3.0中名爲builtins的模塊。
>>> import random >>> random.random() #選出一個0到1之間的任意浮點數
0.7293494111854583 >>> random.random() 0.7408299666488919 >>> random.randint(1,10) #選出1到10之間的隨機整數
6 >>> random.randint(11,100) 37 >>> random.choice(['A','B','C']) #在一個序列中任意挑選一項
'A' >>> random.choice(['A','B','C']) 'C'
#通常模塊都是導入才能使用的,上面使用標準庫中的random模塊時必須導入。
2.6 其餘數字類型
Python的核心數字類型:整數、浮點數和複數。對於絕大多數程序員來講,須要進行的絕大多數數字處理都知足了。不過,Python還自帶了一些更少見的數字類型。
小數數字:
比其餘數據類型複雜一些,小數是經過一個導入的模塊調用函數後建立的,而不是經過運行常量表達式建立的。從功能上來講,小數對象就像浮點數,只不過它們由固定的位數和小數點,所以小數是有固定的精度的浮點值。例如,使用小數對象,咱們可以使用一個只保留兩位小數位精度的浮點數。此外,可以定義如何省略和截斷額外的小數數字,儘管它對日常的浮點數類型來講帶來了微小的性能損失,小數類型對錶現固定精度的特性(例如,錢的總和)以及實現更好的數字精度是一個理想的工具。
>>> 0.1 + 0.1 + 0.1 - 0.3 #得出來的非0確實一個浮點數 5.551115123125783e-17 >>> print(0.1 + 0.1 + 0.1 - 0.3) 5.551115123125783e-17 >>> from decimal import Decimal >>> Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3') Decimal('0.0')
#從上面的例子能夠看出,浮點數缺少精確性,由於用來存儲數值的空間有限。結果接近0可是卻沒有足夠的位數去實現這樣的精度。正如上面顯示的,可以經過調用在decimal模塊中的Decimal的構造函數建立一個小數對象,並傳入一個字符串,這個字符串有咱們但願在結果中顯示的小數位數。當不一樣的精度的小數在表達式中混編時,python自動升級爲小數位數最多的。
>>> import decimal >>> decimal.Decimal(1) / decimal.Decimal(7) Decimal('0.1428571428571428571428571429') >>> decimal.getcontext().prec=4 #設置輸出爲小數點後4位 >>> decimal.Decimal(1) / decimal.Decimal(7) Decimal('0.1429') >>> 1999 + 1.33 2000.33 >>> decimal.getcontext().prec=2 >>> pay = decimal.Decimal(str(1999 + 1.33)) >>> pay Decimal('2000.33')
#能夠設置全局精度,decimal模塊中的其餘工具能夠用來設置全部小數數值的精度、設置錯誤處理等。例如,這個模塊中的一個上下文對象容許指定精度(小數位數)和舍入模式(捨去、進位等)。該精度全局性地適用於調用線程中建立的全部小數。
另外還有分數,能夠用Fraction模塊。
2.7 集合
Python 2.4引入了一種新的類型--集合(set),這是一些惟一的、不可變的對象的一個無序集合(collection),這些對象支持與數學集合理論相應的操做。根據定義,一個項在集合中只能出現一次,無論將它添加了多少次。一樣,集合有着普遍的應用,尤爲是在涉及數字和數據庫的工做中。
由於它是其餘對象的集合,所以,它具備列表和字典這樣的對象的某些共同行爲。例如集合是能夠迭代的,能夠根據須要增加或縮短,而且可以包含各類對象類型。將會看到,一個集合的行爲很像一個無值的字典的鍵,可是,它還支持額外的操做。
然而因爲集合是無序的,而且不會把鍵匹配到值,他們既不是序列也不是映射類型;它們是自成一體的類型。
>>> x = set('abcde') #經過用set的方式來建立集合 >>> y = set('bdxyz') >>> type(x) #能夠查看一下x的類型
<class 'set'> >>> x #輸出一下能夠看出集合是無序的
{'a', 'd', 'e', 'c', 'b'} >>> 'e' in x #若是e在集合x中就爲真
True >>> x - y #求差集,在x中但沒有在y中的元素
{'a', 'c', 'e'} >>> x | y #x和y的並集
{'a', 'b', 'd', 'c', 'e', 'x', 'z', 'y'} >>> x & y #x和y的交集
{'d', 'b'} >>> x ^ y #對稱差集,項目出如今x或者y中,可是不會同時出如今二者之中
{'a', 'c', 'e', 'x', 'z', 'y'} >>> x > y, x < y #測試y中的元素是否都在x中,或者x的元素都在y中
(False, False)
>>> x=set('abcd')
>>> y=set('abc')
>>> x > y, x < y
(True, False)
#集合經過表達式操做符支持通常的數學集合運算。注意,不能再通常序列上應用這些表達式,必須經過序列建立集合後才能使用這些工具。
>>> z = x.intersection(y) #返回一個新的集合,包含x和y中的公有的元素
>>> z {'a', 'c', 'b'} >>> z.add('SPAM') #將SPAM添加到z集合中
>>> z {'a', 'SPAM', 'c', 'b'}
>>> z.update(set(['X','Y'])) #在z集合中添加一個集合,不加set也能夠裏面添加列表什麼的,也就是添加多個元素
>>> z {'a', 'X', 'SPAM', 'Y', 'c', 'b'} >>> z.remove('b') #刪除z集合中的b元素
#除了表達式,集合對象還提供了對應這些操做的方法,以及更多的支持改變集合的方法,集合add方法插入一個項目、update是按位置求並集,remove根據值刪除一個項目(在任何集合實例或集合類型名上運行dir來查看全部可用的方法)。
>>> for item in set('abc'): print(item *3) #支持for循環
... aaa ccc bbb >>> S = set([1,2,3])
>>> S | set([3,4])
{1, 2, 3, 4} >>> S | [3,4] #集合和列表是不能進行上面的那些差集之類的
Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for |: 'set' and 'list' >>> S.union([3,4]) #返回一個新的集合,返回S和【3,4】中的相同元素之外的全部元素
{1, 2, 3, 4} >>> S.intersection((1,3,5)) #這就是求S和(1,3,5)的交集
{1, 3} >>> S.issubset(range(-5,5)) #判斷S中的每個元素是否都在(-5,5)中
True
#上面的例子能夠看出,做爲可迭代的容器,集合也能夠用於len、for循環和列表解析這樣的操做中。然而,因爲它們都是無序的,因此不支持像索引和分片這樣的操做,儘管上上面介紹的集合表達式一般須要兩個集合,可是上面的例子能夠看出,他們基於方法的對應形式每每對任何可迭代類型也有效。
#我這裏用的是Python 3.0,能夠看出集合輸出的是一個字典的花括號的形式,這個語法是有意義的,由於集合基本上就像是無值的字典,集合的項是無序的、惟一的、不可改變的,所以,他們的行爲和字典的鍵很像。因爲字典鍵列表在Python 3.0中是視圖對象,它支持像交集和並集這樣的相似集合的行爲這種類似性更加驚人。
#注意,在Python中{}仍然是一個字典。空的集合必須經過內置函數set來建立。
#不可變限制和凍結集合。集合是強大而靈活的對象,可是,它們只能包含不可變(便可散列)對象類型。所以,列表和字典不能嵌入到集合中,可是,若是須要存儲複合值的話,元組是能夠嵌入的。例如,集合中的元組能夠用來表示日期、記錄、IP地址等。集合自己也是不可改變的,所以,不能直接嵌入到其餘集合中;若是須要在另外一個集合中存儲一個集合,能夠像調用set同樣來調用frozenset,可是,它建立一個不可變的集合,該集合不可修改而且能夠嵌套到其餘集合中。
#爲何使用集合?集合操做有各類各樣常見的用途,其中一些比數字更加實用。例如,因爲項在集合中只能存儲一次,集合(set)能夠用來把重複項從其餘集合(collection)中過濾掉。直接把集合(collection)轉換爲一個集合(set),而後再轉換回來便可(由於集合是可迭代的,這裏的list調用對其有效):以下面的例子
>>> L = [1,2,1,3,2,4,5] >>> set(L) {1, 2, 3, 4, 5} >>> L = list(set(L)) >>> L [1, 2, 3, 4, 5] >>> type(L) <class 'list'>
#當遍歷圖形或其餘的迴環結構的時候,集合能夠用來記錄已經訪問過的位置。當傳遞性模塊重載和繼承樹列表程序實例,必須確保訪問過的項再也不循環。儘管把訪問狀態做爲鍵記錄到字典中很搞笑,但集合提供了幾乎等同的一種替代方式。
#最後在處理較大的數據集合的時候(例如,數據庫查詢結果),兩個集合的交集包含了兩個領域中共有的對象,並集包含了兩個集合中的全部項目。
2.8 布爾型
對於Python的布爾類型有一些爭論,bool本來是一個數字,由於它有兩個值True和False,不過是整數1和0以不一樣的形式顯示後的定製版本而已。
Python現在正式地有了一種明確的布爾型數據類型,叫作bool,其值爲True和False,而且其值True和False是預先定義的內置的變量名。在內部在新的變量名True和False是bool的實例,實際上僅僅是內置的整數類型int的子類(以面向對象的觀點來看)。True和False的行爲和整數1和0是同樣的,除了它們有特定的顯示邏輯:它們是做爲關鍵字True和False顯示的,而不是數字1和0(從技術上來說,bool爲它的兩個對象從新定義了str和repr的字符串格式)。
因爲這個定製,布爾表達式和交互提示模式的輸出就做爲關鍵字True和False來顯示,而不是曾經的1和0.此外,布爾型讓真值更精確。例如,一個無限循環如今可以編寫成while True:而不是while 1:。相似地,經過使用flag = False,能夠更清楚地設置標誌位。
還有對於其餘實際的用途,你可以將True和False看作是預約義的設置爲整數1和0的變量。大多數程序員都曾把True和False預先賦值爲1和0:由於True僅僅是定製了顯示格式的整數1,在Python中True+4獲得了5!
>>> type(True) <class 'bool'> >>> isinstance(True,int) True >>> True == 1 True >>> True is 1 False >>> True or False True >>> True + 4 5
#上面的例子就是對上面介紹的一種展現.
3、動態類型
3.1 變量、對象和引用
當在Python中運行賦值語句a = 3時就屬於:
變量建立:一個變量(也就是變量名),就像a,當代碼第一次給它賦值時就建立了它。以後的賦值將會改變已建立的變量名的值。
變量類型:變量永遠不會有任何的和它有關聯的類型信息或約束。類型的概念是存在對象中而不是變量名中,變量本來是通用的,它只是在一個特定的時間點,簡單的引用一個特定的對象而已。
變量使用:當變量出如今表達式中時,它會立刻被當前引用的對象所代替,不管這個對象是什麼錯誤。此外,全部的變量必須在使用前明確地賦值,使用未賦值的變量會產生錯誤。
總而言之,變量在賦值的時候才建立,它能夠引用任何類型的對象,而且必須在引用以前賦值。
在Python中,每當一個變量名被賦予了一個新的對象,以前的那個對象站應用的空間就會被回收(若是它沒有被其餘的變量名或對象所引用的話)。這種自動回收對象的空間的技術叫作垃圾收集。
在內部,Python它在每一個對象中保持了一個計數器,計數器記錄了當前指向該對象的引用數目。一旦(並精確在同一時間)這個計數器被設置爲零,這個對象的內存空間就會自動回收。在前面的介紹中,假設每次x都被賦值給一個新的對象,而前一個對象的引用計數器爲零,就會致使它的空間被回收。
3.2 共享引用
在交互模式下,引入另外一個變量,並看一下變量名和對象的變化:
>>> a = 3 >>> b = a >>> b 3
#像上面那樣,實際的效果是變量a和b都引用了相同的對象(也就是說指向了相同的內存空間)。這在Python中叫作共享引用--多個變量名引用了同一個對象。
>>> a = 3 >>> b = a >>> a = 'spam' >>> b 3
#從上面的例子能夠看出,雖然a指向了新的對象,可是b仍是使用原來的變量也就是使用原來的內存空間。要想b跟着變化還得再來下b=a。
>>> L1 = [2,3,4] >>> L2 = L1 >>> L1[0] = 24 >>> L1 [24, 3, 4] >>> L2 [24, 3, 4]
#上面的例子是共享引用和在原處修改的例子,上面的例子,沒有改變L1,改變了L1所引用的對象的一個元素。這類修改會覆蓋列表對象中的某部分。由於這個列表對象是與其餘對象共享的(被其餘對象引用),那麼一個像這樣在原處的改變不只僅會對L1有影響。也就是說,必須意識到當作了這樣的修改,它會影響程序的其餘部分。這裏也對L2產生影響,由於它與L1都引用了相同的對象。另外,咱們實際上並無改變L2,可是它的值將發生變化,由於它已經被修改了。
>>> L1 = [2,3,4] >>> L2 = L1[:] >>> L1[0] = 24 >>> L1 [24, 3, 4] >>> L2 [2, 3, 4]
#若是不想L1變化了L2也要跟着變化,須要Python拷貝對象,而不是建立引用。有不少種拷貝一個列表的辦法,包括內置列表函數以及標準庫的copy模塊。上面的方式是一種從頭至尾的分片方法。這裏L1的修改不會影響L2,由於L2引用的是L1所引用對象的一個拷貝。也就是說,兩個變量指向了不一樣的內存區域。
#注意這種分片技術不會應用在其餘的可變的核心類型(字典和集合,由於它們不是序列)上,複製一個字典或集合應該使用X.copy()方法調用。並且,注意標準庫中的copy模塊有一個通用的複製任意對象類型的調用,也有一個拷貝嵌套對象結構(例如,嵌套了一個列表的字典)的調用:
>>> L1=[1,2,3] >>> import copy >>> X = copy.copy(L1) #淺copy >>> X = copy.deepcopy(L1) #深copy