Python認為一切皆為對象;比如我們初始化一個list時:
li = list('abc')
實際上是實例化了內置模塊builtins(python2中為__builtin__模塊)中的list類;

class list(object): def __init__(self, seq=()): # known special case of list.__init__ """ list() -> new empty list list(iterable) -> new list initialized from iterable's items # (copied from class doc) """ pass
驗證:

In [1]: li = list('abc') In [2]: li.__class__ Out[2]: list In [3]: li.__class__.__name__ Out[3]: 'list'
1. Python對象特性
python使用對象模型來存儲數據。構造任何類型的值都是一個對象。所有python對象都擁有三個特性:身份、類型、值:
1)身份:每個對象都有一個唯一的身份標識自己,任何對象的身份可以使用內建函數 id() 來得到。
2)類型:對象的類型決定了該對象可以保存什么類型的值,可以進行什么樣的操作,以及遵循什么樣的規則。可以使用 type() 函數查看python對象的類型。type()返回的是對象而不是簡單的字符串。
3)值:對象表示的數據。
python不需要事先聲明對象類型,當python運行時,會根據“=“右側的數據類型來確定變量類型;
2.Python對象類型
(1)標准類型(基本數據類型)
a) .數字(分為幾個字類型,其中三個是整型)
- Integer 整型
- Boolean 布爾型
- Long integer 長整型
- Floating point real number 浮點型
- Complex number 復數型
b) String 字符串
c) List 列表
d) Tuple 元祖
e) Dictionary 字典
(2)其他內建類型
類型、Null對象(None)、文件、集合/固定集合、函數/方法、模塊、類
3. 基本對象類型分類
有3種不同的模型可以幫助我們對基本類型進行分類
1)存儲類型
一個能保存單個字面對象的類型,稱為原子或標量存儲;可以容納多個對象的類型,稱為容器存儲;並且所有的python容器對象都可以容納不同類型的對象;
注意,python沒有字符類型,所以雖然字符串你看上去像容器類型,實際是原子類型
2)更新模型(是否可變)
這里所說的是否可變,可更新是針對的對象的值而言的;是在對象身份不變的情況下(id不變),值是否可更新;

s = 'abc' print('id of s: ', id(s)) s = 'xyz' print('id of s: ', id(s))
結果:
id of s: 41643960
id of s: 46319184
上例中,很多人會說s是字符串,也可變啊,但是注意,這里s指向的對象發生了變化(id值發生了變化),所以這不是我們所說的可更新;讓我們看一下list

li = ['a', 'b'] print('li before update', li) print('id of li: ', id(li)) li[0] = 'x' print('li after update', li) print('id of li: ', id(li))
結果:
li before update ['a', 'b'] id of li: 48447304 li after update ['x', 'b'] id of li: 48447304
li的值發生了變化,但是li還是原來的對象(id值不變)
另外,對於元祖,元祖本身不可變,但是當元祖存在可變元素時,元祖的元素可變,比如

t = (1, ['a','b']) print('t before update', t) print('id of t: ', id(t)) t[1][0] = 'x' print('t after update', t) print('id of t: ', id(t))
結果:
t before update (1, ['a', 'b']) id of t: 48328968 t after update (1, ['x', 'b']) id of t: 48328968
注意:在使用for循環來遍歷一個可更新對象過程中,增加刪除可更新對象容器的大小會得到意想不到的結果(不期望的結果)甚至出現異常,其中對於字典,直接報錯;
直接遍歷列表:

1 lst = [1, 1, 0, 2, 0, 0, 8, 3, 0, 2, 5, 0, 2, 6] 2 3 for item in lst: 4 if item == 0: 5 lst.remove(item) 6 print(lst) #結果為 [1, 1, 2, 8, 3, 2, 5, 0, 2, 6]
遍歷索引:

1 lst = [1, 1, 0, 2, 0, 0, 8, 3, 0, 2, 5, 0, 2, 6] 2 3 for item in range(len(lst)): 4 if lst[item] == 0: 5 del lst[item] 6 print(lst) #結果為IndexError: list index out of range
字典:

1 dct = {'name':'winter'} 2 for key in dct: 3 if key == 'name': 4 di['gender'] = 'male' 5 print(dct) #結果報錯RuntimeError: dictionary changed size during iteration
for循環來遍歷可變對象時,遍歷順序在最初就確定了,而在遍歷中如果增加刪除了元素,更新會立即反映到迭代的條目上,會導致當前索引的變化,這樣一是會導致漏刪或多增加元素,二是會導致遍歷超過鏈表的長度。那么有解決方案嗎?
a) 通過創建一個新的可變對象實現,比如:
b) 通過while循環

1 #通過創建新的copy 2 for item in lst[:]: 3 if item == 0: 4 lst.remove(item) 5 print (lst) 6 #通過while循環 7 while 0 in lst: 8 lst.remove(0) 9 print (lst)
更多的內容,看我關於“迭代器”的博客
3)訪問模型
序列是指容器內的元素按從0開始的索引順序訪問;
字典的元素是一個一個的鍵值對,類似於哈希表;通過獲取鍵,對鍵執行一個哈希操作,根據計算的結果,選擇在數據結構的某個地址中存儲你的值。任何一個值的存儲地址取決於它的鍵;所以字典是無序的,鍵必須是不可變類型(對於元祖,只能是元素不可變的元祖)
總結:
既然字符串,列表,元祖,字典都是對象,那么任何一種實例化的對象都會有相同的方法,下面讓我們來依次來認識這些常見的數據類型:
4. 字符串
1)創建字符串
兩種方式:
#直接創建字符串引用 s = 'winter' #通過使用str()函數創建 s = str(123)
2)字符串方法
作為內建對象,字符串類的定義在內建模塊builtins中,通過源碼可以查看到所有字符串方法;如果你在用pycharm,那么更加方便,選中str類以后,點擊按鈕"Scroll from Source";就可以看到所有方法的列表;
針對每一種方法都有詳細的方法文檔;在這里吐血一一羅列出,有的注釋部分很重要:

1 '''字符串方法''' 2 3 #index,字符串查找,返回第一個匹配到的索引值,沒有就報錯,可以提供開始,結束位置 4 s = 'xyzabc' 5 ret = s.index('za') #結果為2 6 ret = s.index('z',2) #結果為2 7 #rindex,反向查找,結果和index方法得到的結果一樣 8 #find,也是字符串查找,與index不同的是找不到時,不會報錯,而是返回-1,注意bool(-1)為True 9 10 11 #split,字符串分隔,如果不指定分割符,則默認采用任意形式的空白字符:空格,tab(\t),換行(\n),回車(\r)以及formfeed 12 res = 'a b c d\ne'.split() #結果res為['a', 'b', 'c', 'd', 'e'] 13 res = 'a:b:c:d'.split(':') #結果為['a', 'b', 'c', 'd'] 14 #rsplit,從字符串尾部開始分割,沒有設置maxsplit參數時和split的結果一樣 15 #splitlines用於將多行字符串,列表的每個元素為一行字符串,默認不帶換行符 16 17 18 #partition,類似於s.split(sep, 1),只是輸出是一個包括了sep的元祖,且沒有默認分隔符sep 19 res = 'a:b:c:d'.partition(':') #結果為('a', ':', 'b:c:d') 20 #rpartition,從字符串末尾開始執行partition方法 21 res = 'a:b:c:d'.rpartition(':') #結果為('a:b:c', ':', 'd') 22 23 24 #strip,去掉字符串兩端的字符,如果沒指定字符,則默認去掉任意形式的空白字符:空格,tab(\t),換行(\n),回車(\r)以及formfeed 25 res = 'abcd'.strip('a') #結果res為'bcd' 26 res = ' abcd \n'.strip() #結果res為'abcd',可以通過len(res)驗證 27 #rstrip,去掉右端的字符 28 #lstrip,去掉左端的字符 29 30 31 #join,字符串拼接 32 #format,字符串格式化 33 #解決萬惡的‘+’號,每次'+'操作都會創建一個新的對象,就需要在內存空間開辟一塊新的區域來存儲;所以大量使用'+'會浪費內存空間 34 #解決方法1,使用join 35 #join,字符串拼接 36 li = ['a', 'b'] 37 res = ':'.join(li) #使用字符串來拼接一個可迭代對象的所有元素,結果res為'a:b' 38 #解決方法2,使用format,有兩種方式: 39 #方式1,其中{0}可以簡寫為{}: 40 res = 'my name is {0}, my age is {1}'.format('winter',30) #{0},{1}為實參的索引 41 #方式2: 42 res = 'my name is {name}, my age is {age}'.format(name='winter', age=30) 43 #或者直接下面這樣 44 userInfo = {'name':'winter','age':30} 45 res = 'my name is {name}, my age is {age}'.format(**userInfo) 46 #或者用format_map(python3.x新增) 47 userInfo = {'name':'winter','age':30} 48 res = 'my name is {name}, my age is {age}'.format_map(userInfo) 49 #解決方法3,除了format以外,還可以使用占位符%,看上去沒那么高級,同樣有兩種方式 50 #方式1 51 res = 'my name is %s, my age is %s'%('winter',30) 52 #方式2 53 userInfo = {'name':'winter','age':30} 54 res = 'my name is %(name)s, my age is %(age)s'%userInfo 55 #結果為'my name is winter, my age is 30' 56 57 #replace,字符串替換,因為字符串為不可變數據類型,所以原字符串不會改變,改變的字符串以返回值形式返回 58 s = '123xyz' 59 ret = s.replace('1','a') #結果s不變,ret為'a23xyz' 60 ret = s.replace('12', 'ab') #結果為'ab3xyz' 61 62 63 #maketrans和translate,一對好基友;用於字符串替換和刪除,很好用,python2.x與python3.x語法不同 64 #maketrans用於創建翻譯表,translate用於翻譯表 65 s = 'abccba' 66 trans_table = str.maketrans('ab','12','c') 67 res = s.translate(trans_table) #結果為'1221',注意與replace的區別 68 69 70 s.count(strings) #count,統計字符串中字符的數目 71 72 73 s.encode() #以某種編碼格式編碼,比如utf-8 74 75 76 #大小寫切換類方法 77 s = 'aBcD' 78 res = s.capitalize() #首字母大寫,結果res為'Abc' 79 res = s.lower() #所有字母小寫,結果res為'abcd',注意僅對ASCII編碼的字母有效 80 res = s.casefold() #所有字母小寫,結果res為'abcd',注意對unicode編碼的字母有效 81 res = s.upper() #所有字母大寫,結果res為'ABCD' 82 res = s.swapcase() #字符串中大小寫互換,結果res為'AbCd' 83 s = 'aB cD,ef' 84 res = s.title() #每個單詞首字母大寫,結果res為'Ab Cd,Ef',其判斷“單詞”的依據則是基於空格和標點 85 86 87 #字符串判斷類方法,以下方法除了isspace()以外,對於空字符串都返回False 88 s.isalpha() #判斷字符串是否全為字母,等價於^[a-zA-Z]+$ 89 s.islower() #判斷字符串中字母部分是否全為小寫字母,可以有其他字符,但是至少要有一個小寫字母,等價於[a-z]+ 90 s.isupper() #判斷字符串中字母部分是否全為小寫字母,可以有其他字符,但是至少要有一個小寫字母,等價於[A-Z]+ 91 s.istitle() #判斷字符串首字母是否全為大寫,可以有其他字符 92 s.isnumeric() #判斷字符串是否全為數字(包括unicode數字,羅馬數字,漢字數字) 93 s.isdigit() #也是判斷字符串是否全為數字(包括unicode數字,羅馬數字) 94 s.isdecimal() #判斷字符串是否全為十進制數字(包括unicode數字) 95 s.isalnum() #判斷字符串是否為數字與字母的組合,等價於^[0-9a-zA-Z]+$ 96 s.isidentifier() #判斷標識符是否合法 97 s.isspace() #判斷是否為任意形式的空白字符:空格,tab(\t),換行(\n),回車(\r)以及formfeed 98 s.isprintable() #判斷字符串是否可打印 99 s.startswith(strings) #判斷字符串是否以某個字符串開頭 100 s.endswith(stings) #判斷字符串是否以某個字符串結尾 101 102 103 #center,ljust,rjust,zfill字符串排版,填充 104 s = '123' 105 res = s.center(50,'-') #center是字符串居中,結果為-----------------------123------------------------ 106 #ljust為居左,rjust為居右,zfill使用0來左填充 107 108 109 s.expandtabs() #expandtables,用於將字符串中的tab字符轉換為空格,如果沒有指定tabsize,默認為8個
5. 列表
1)創建列表
三種方式:
a = ['a','b','c'] #直接創建 b = list('abc') #通過創建list實例創建,結果為['a','b','c'] c = [x for x in range(4)] #列表推導式,結果為[1,2,3,4]
注意,第二種方法,我們來看一下它的構造函數:

def __init__(self, seq=()): # known special case of list.__init__ """ list() -> new empty list list(iterable) -> new list initialized from iterable's items # (copied from class doc) """ pass
接收的參數是一個可迭代對象,即擁有__iter__方法的對象,元祖,集合和字典的構造函數的參數都是可迭代對象;
第三種方法稱為列表推導式,語法為
[expr for iter_var in iterable] #迭代iterable里所有內容,每一次迭代,都把iterable里相應內容放到iter_var中,再在表達式中應用該iter_var的內容,最后用表達式的計算值生成一個列表。
擴展形式
[expr for iter_var in iterable if cond_expr] #加入了判斷語句
2)列表方法
與查看字符串方法類似,可以通過源碼查看,這里也一一羅列出:

1 #增,append,insert,extend 2 #追加append 3 li = ['a','b','c'] 4 li.append('d') #結果li = ['a','b','c','d'],list是可變類型,所以li元素的增加刪除會影響源列表 5 #插入insert 6 li = ['a','b','c'] 7 li.insert(1,'d') #結果li = ['a','d','b','c'] 8 #extend,將一個可迭代對象增加追加到列表里 9 li = ['a','b','c'] 10 li.extend(['x','y']) #結果li = ['a','b','c','x','y'] 11 li.extend(('m','n')) #結果li = ['a', 'b', 'c', 'x', 'y', 'm', 'n'] 12 13 14 #刪,remove,pop,clear 15 #remove,刪除第一個與參數值相等的元素,刪除不存在的元素報ValueError 16 li = ['a','b','c','a'] 17 li.remove('a') #結果li = ['b', 'c', 'a'] 18 #pop,參數為索引值,彈出對應索引值的元素,返回值為彈出的元素,默認為彈出最后一個元素,索引不存在報IndexError 19 li = ['a','b','c','a'] 20 res = li.pop(1) #結果res = ‘b',li = ['a', 'c', 'a'] 21 #clear,清空列表,但是列表對象依然存在,沒有被回收 22 li = ['a','b','c','a'] 23 li.clear() #結果li = [] 24 25 26 #查,count,index 27 #count,統計列表內元素個數 28 li = ['a','b','c','a'] 29 res = li.count('a') #結果res = 2 30 #index,查找元素對應的索引值,不存在報ValueError 31 li = ['a', 'b', 'c', 'a'] 32 res = li.index('a') #結果res = 0 33 34 35 #reverse,反轉 36 li = ['a','b','c'] 37 li.reverse() #結果li = ['c','b','a'] 38 39 40 #sort,根據key排序,默認從小到大,同樣可以實現反轉 41 li = ['c','b','a'] 42 li.reverse() #結果li = ['a', 'b', 'c'] 43 li = [[4,5,6], [7,2,5], [6,1,8]] 44 li.sort(key=lambda x:x[1]) #結果li = [[6, 1, 8], [7, 2, 5], [4, 5, 6]],根據li元素的第二個值進行排序 45 46 47 #copy,淺復制,注意與賦值和深復制的區別 48 li = [[1,2,3], 'a'] 49 li_new = li.copy() 50 li_new[0][0] = 4 #li_new = [[4, 2, 3], 'a'],但是li也發生了變化li = [[4, 2, 3], 'a'] 51 li_new[1] = 'b' #li_new = [[1, 2, 3], 'b'],但是li不變,[[1, 2, 3], 'a']
6. 元祖
1)創建元祖
兩種方式:
t = (1,2,3) #直接創建 t = tuple([1,2,3]) #通過tuple函數創建,參數為可迭代對象,結果為(1,2,3)
2)元祖方法
和字符串,一樣,通過源碼查看,這里一一列出:

#count,統計元祖內元素個數 t = (1,2,3,1) res = t.count(1) #結果res = 2 #index,查找元素對應的索引值,不存在報ValueError t = (1,2,3,1) res = t.index(1) #結果res = 0
元祖的方法很少,而且元祖對象是不可變的,元組不可變的好處。保證數據的安全,比如我們傳數據到一個不熟悉的方法或者數據接口, 確保方法或者接口不會改變我們的數據從而導致程序問題。
注意,因為()處理用於定義元祖,還可以作為分組操作符,比如if ( a> b) and (a < c)中的(),且python遇到()包裹的單一元素,首先會認為()是分組操作符,而不是元組的分界符,所以一般我們對於元組,會在)之前再加入一個,
a = (1,2,3,)
3) 列表vs元組
使用不可變類型變量的情況:如果你在維護一些敏感數據,並且需要把這些數據傳遞給一個不了解的函數(或一個根本不是你寫的API),作為一個只負責一個軟件某一部分的工程師,如果你希望你的數據不要被調用的函數篡改,考慮使用不可變類型的變量;
需要可變類型參數的情況:管理動態數據集合時,你需要先創建,然后漸漸地不定期地添加,或者有時需要移除一些單個的元素,這時必須使用可變類型對象;將可變類型變量作為參數傳入函數,在函數內可以對參數進行修改,可變類型變量也會相應修改;
7. 序列共有特性
字符串,列表,元祖統稱序列,是可以順序訪問的;他們的關系和共有特性如下:
1)相互轉換
2)序列操作符
a)根據索引取值,可以正向索引,也可以反向索引

li = [1,2,3,4] res = li[0] #結果為1 res = li[-1] #結果為4 li[1] = ['a'] #結果li = [1,'a',3,4]
b)切片
seq[ind1:ind2:step],原則是顧頭不顧尾

li = [1,2,3,4] res = li[:] #結果為[1, 2, 3, 4] res = li[1:] #結果為[2,3,4] res = li[:-2] #結果為[1,2] res = li[1:3] #結果為[2,3] res = li[::2] #取索引值為偶數的元素[1,3],對應的li[1::2]為取索引值為基數的元素 res = li[::-1] #步進為-1,結果為[4, 3, 2, 1] res = li[-1:-3:-1] #結果為[4,3] res = li[3:1:-1] #結果為[4,3] res = li[1:1] #結果為[] li[1:2] = ['a','b'] #結果li = [1, 'a', 'b', 3, 4] li[1:1] = [9] #結果li = [1, 9, 'a', 'b', 3, 4],相當於插入
注意序列不能讀寫不存在的索引值,但是切片可以

li = [1,2,3] li[9] #報IndexError li[1:9] #結果為[2,3] li[8:9] = [9] #結果為[1,2,3,9]
c)重復操作符*

[1]*3 #結果為[1,1,1] [1,2,3]*3 #結果為[1, 2, 3, 1, 2, 3, 1, 2, 3]
d)連接操作符+

[1,2,3]+[4,5,6] 結果為 [1, 2, 3, 4, 5, 6]
e)成員關系操作符in, no in

li = [1,2,3] 1 in li #結果為True 4 not in li #結果為True
f)刪除序列對象,元素關鍵字del

l = [1,2,3] del l[0] #結果l為[2,3] del l #結果訪問l后,報NameError
3)可操作內建函數

1 #enumerate,枚舉 2 li = ['a','b','c'] 3 for item in enumerate(li): 4 print(item) 5 ''' 6 結果為: 7 (0, 'a') 8 (1, 'b') 9 (2, 'c') 10 ''' 11 for item in enumerate(li,5): 12 print(item) 13 ''' 14 結果為: 15 (5, 'a') 16 (6, 'b') 17 (7, 'c') 18 ''' 19 20 21 #len 22 len([1,2,3]) #結果為3 23 len([[1,2],[3,4]]) #結果為2 24 25 26 #max, min 27 max([1,2,3]) #結果為3 28 min([1,2,3]) #結果為1 29 30 31 #sorted,注意與list.sort()方法的區別 32 li = [[1,4],[2,3],[3,2]] 33 res = sorted(li, key=lambda x:x[1]) #結果res為[[3, 2], [2, 3], [1, 4]] 34 35 36 #zip,和倒置有點像 37 l1 = [1,2,3] 38 l2 = [1,2,3] 39 for item in zip(l1,l2): 40 print(item) 41 ''' 42 結果為: 43 (1, 1) 44 (2, 2) 45 (3, 3) 46 ''' 47 l1 = [1,2,3] 48 l2 = [1,2] 49 for item in zip(l1,l2): 50 print(item) 51 ''' 52 結果為: 53 (1, 1) 54 (2, 2) 55 '''
8. 字典
字典是Python語言中唯一的映射類型。映射對象類型里哈希值(鍵,key)和指向的對象(值,value)是一對多的關系;
特性:
a)字典是無序的可變的容器類型
b)字典的鍵是唯一的,且必須是不可變類型,如果是元組,要求元組的元素也不可變(因為值的內存地址與鍵的哈希值有關)
1)創建字典

1 #直接創建 2 d = { 3 'name':'winter', 4 'age':18, 5 'hobbies':['basketball','football'] 6 } 7 8 #通過dict函數創建,參數為可迭代對象,字典或列表組成的任意形式;[(),()]或((),())或([],[])或[[],[]]或使用dict(zip()) 9 d = dict([('name', 'winter'), 10 ('age',18), 11 ('hobbies',['basketball','football'])]) #結果為{'age': 18, 'hobbies': ['basketball', 'football'], 'name': 'winter'} 12 13 #通過字典推導式 14 d = {x:y for x, y in zip(['name','age','hobbies'],['winter',18,['basketball','football']])} #結果為{'age': 18, 'hobbies': ['basketball', 'football'], 'name': 'winter'} 15 d = {x:y for x, y in zip(['name','age','hobbies'],['winter',18,['basketball','football']]) if x=='name'}#結果為{'name': 'winter'} 16 17 #通過字典方法fromkeys()創建一個含有默認值的字典,fromkeys方法是dict類的靜態方法 18 d = dict.fromkeys(['name','gender'], 'unknown') #結果{'gender': 'unknown', 'name': 'unknown'}
2)字典方法

1 #增 2 d = { 3 'name':'winter', 4 'age':18, 5 'hobbies':['basketball','football'] 6 } 7 #update,類似於list.extend(),將鍵值對參數加到字典中,對於已存在的更新 8 d.update({'gender':'male'}) #結果為:{'age': 18, 'gender': 'male', 'hobbies': ['basketball', 'football'], 'name': 'winter'} 9 10 11 #刪 12 d = { 13 'name':'winter', 14 'age':18, 15 'hobbies':['basketball','football'] 16 } 17 #popitem,隨機刪除一組鍵值對,並返回該組鍵值對 18 res = d.popitem() #結果為res = ('hobbies', ['basketball', 'football']), d為{'age': 18, 'name': 'winter'} 19 #pop,刪除指定鍵的鍵值對,返回對應的值 20 res = d.pop('name') #結果為res = 'winter', d為{'age': 18} 21 #clear,清空字典,字典對象還在,沒有被回收 22 d.clear() #結果d為{} 23 #del關鍵字,可以用於刪除字典對象和元素 24 d = { 25 'name':'winter', 26 'age':18, 27 'hobbies':['basketball','football'] 28 } 29 del d['hobbies'] #結果為 {'age': 18, 'name': 'winter'} 30 del d #結果訪問d,報NameError 31 32 33 #查 34 d = { 35 'name':'winter', 36 'age':18, 37 'hobbies':['basketball','football'] 38 } 39 #get,根據鍵取對應的值,沒有對應的鍵,就返回第二個參數,默認為None 40 res = d.get('name', 'not found') #res = ’winter' 41 res = d.get('gender', 'not found') #res = 'not found' 42 #setdefault,根據鍵取對應的值,如果不存在對應的鍵,就增加鍵,值為第二個參數,默認為None 43 res = d.setdefault('name','winter') #res = ’winter' 44 res = d.setdefault('gender','male') #res = 'male',d變為{'age': 18, 'gender': 'male', 'hobbies': ['basketball', 'football'], 'name': 'winter'} 45 #keys,獲得所有的鍵 46 res = d.keys() #res = dict_keys(['name', 'age', 'hobbies', 'gender']) 47 #values,獲得所有的值 48 res = d.values() #res = dict_values(['winter', 18, ['basketball', 'football'], 'male']) 49 #items,獲得所有的鍵值對 50 res = d.items() #res = dict_items([('name', 'winter'), ('age', 18), ('hobbies', ['basketball', 'football']), ('gender', 'male')]) 51 52 53 #copy方法, 和list.copy一樣,是淺復制
3)字典元素的訪問

1 dic = {'name':'winter', 'age':18} 2 ''' 3 下面3中方式的結果都為 4 name winter 5 age 18 6 ''' 7 #方式1 8 for item in dic: 9 print(item, dic[item]) 10 #方式2 11 for item in dic.keys(): 12 print(item, dic[item]) 13 #方式3 14 for k,v in dic.items(): 15 print(k, v)
推薦方式1),采用了迭代器來訪問;
4)字典vs列表
a) 字典:
- 查找和插入的速度極快,不會隨着key的數目的增加而增加(直接查找hash后得到的內存地址);
- 需要占用大量的內存,內存浪費多(大量的hash值,占用內存你空間)
- key不可變
- 默認無序
b) 列表:
- 查找和插入的時間隨着元素的增加而增加
- 占用空間小,浪費內存很少
- 通過下標查詢
- 有序
9. 集合
這是高一數學的內容了
集合對象是一組無序排列的值,分為可變集合(set)和不可變集合(frozenset);可變集合不可hash;不可變集合可以hash,即可以作為字典的鍵;
特性:
a) 無序性,無法通過索引訪問
b) 互異性,元素不可重復,即有去重的功能
1) 創建集合

1 #直接創建可變集合 2 s1 = {1,2,3,3} #結果,python3.x為{1,2,3},python2.x為set([1, 2, 3]),因為集合不允許有重復元素,所以只有一個3元素 3 #通過函數創建 4 s2 = set([1,2,3,4]) #創建可變集合{1, 2, 3, 4} 5 s3 = frozenset([1,2,3,3]) #創建不可變集合,結果為frozenset({1, 2, 3})
2) 集合方法和操作符
這里直接用一張表:
這里只列出可變集合的方法示例,因為不可變集合的方法可變集合都有
a) 單個集合的操作

1 #集合 2 3 #直接創建可變集合 4 s1 = {1,2,3,3} #結果,python3.x為{1,2,3},python2.x為set([1, 2, 3]),因為集合不允許有重復元素,所以只有一個3元素 5 #通過函數創建 6 s2 = set([1,2,3,4]) #創建可變集合{1, 2, 3, 4} 7 s3 = frozenset([1,2,3,3]) #創建不可變集合,結果為frozenset({1, 2, 3}) 8 9 10 s1 = {1,2,3} 11 12 #增 13 s1.add('456') #結果s1 = {1, 2, 3, '456'} 14 s1.update('789') #結果s1 = {1, 2, 3, '7', '8', '9', '456'} 15 16 #刪 17 res = s1.pop() #結果res = 1,s1 = {2, 3, '7', '8', '9', '456'} 18 s1.remove(3) #結果s1 = {2, '7', '8', '9', '456'} 19 s1.discard(4) #結果s1 = {2, '7', '8', '9', '456'},同時不報Error 20 s1.clear() #結果s1 = set() 21 22 #淺復制 23 s1 = {1,2,3} 24 s2 = s1.copy() #結果s2 = {1,2,3}
b) 集合之間的操作,集合的主要功能

1 s0 = {1,2} 2 s1 = {1,2,3,4} 3 s2 = {3,4,5,6} 4 5 #子集,超級判斷 6 res = s0.issubset(s1) #結果res = True 7 res = s1.issubset(s2) #結果res = False 8 res = s1.issuperset(s0) #結果res = True 9 res = s0 <= s1 #結果res = True 10 11 #並集 12 res = s1.union(s2) #結果res = {1, 2, 3, 4, 5, 6} 13 res = s1 | s2 #結果res = {1, 2, 3, 4, 5, 6} 14 15 #交集 16 res = s1.intersection(s2) #結果為{3, 4} 17 res = s1 & s2 #結果為{3, 4} 18 19 #差集 20 res = s2.difference(s1) #結果res = {5, 6} 21 res = s2 - s1 #結果res = {5, 6} 22 res = s1.difference(s2) #結果res = {1, 2} 23 24 #對稱差集 25 res = s2.symmetric_difference(s1) #結果為{1, 2, 5, 6} 26 res = s2 ^ s1 #結果為{1, 2, 5, 6} 27 28 #在原集合基礎上修改原集合 29 s1.intersection_update(s2) 30 s1.difference_update(s2) 31 s1.symmetric_difference_update(s2)
用一張圖來解釋一下:
2017年9月20日更新
1. 推導式
有列表推導式,字典推導式,集合推導式
1)列表推導式

1 li_1 = [item for item in range(5)] #結果li_1 = [0, 1, 2, 3, 4] 2 3 li_2 = [item for item in range(5) if item > 2] #結果li_2 = [3, 4] 4 5 li_3 = [item if item>2 else 0 for item in range(5)] #結果li_3 = [0, 0, 0, 3, 4] 6 7 li_4 = [(x,y) for x in range(3) for y in range(3,6)] #結果li_4 = [(0, 3), (0, 4), (0, 5), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5)] 8 9 li_raw = [['winter', 'tom', 'lily'], ['winter']] 10 li_5 = [item for li in li_raw for item in li if item.count('l') > 1] #結果li_5 = ['lily']
2)集合推導式
和列表推導式一樣,只要把[]換成{}即可
3)字典推導式
和列表推導式一樣,只是沒有if...else...形式
4)有元祖推導式嗎?
(x for x in range(5))就是元祖推導式呢?
答案是:不是的
(x for x in range(5)得到的是一個生成器
>>>a = (x for x in range(10)) >>>a >>><generator object <genexpr> at 0x0000000004B09F68>
>>>a.__next__()
>>>0
>>>a.__next__()
>>>1