#9 Python列表和元組
前言
Python中有6種序列:列表、元組、字串、Unicode字串、buffer物件和xrange物件。序列通用操作包括:索引、切片、長度、加、乘、最大值、最小值,遍歷和檢查成員。雖然Python有6中內建序列,但是最常用的是列表和元組。所有本博文將深入列表和元組,掌握其方法!
一、列表(list)
看了上面說的,現在是不是一頭霧水,其實上面提到的操作無非不過一些方法而已,熟練應用就掌握了,那先來看看列表的方法吧:
In [3]: dir(list) Out[3]: ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
補充:有些方法有兩個前導下劃線和兩個後置下劃線,這是特殊方法的意思,應用於特殊函式,實際應用中很少用到,常用的是普通方法。
可以看到,列表的方法其實不是很多,但是使用技巧卻很靈活,盤它!
1.初始化列表
列表的初始化前面已經說過了,這裡再來複習一下,被一對方括號括住,元素用逗號隔開就是列表:
In [4]: systems = ['CentOs','Windows', 'Ubuntu']# 元素全是字串的列表 In [5]: systems = ['CentOs','Windows', 'Ubuntu', 666]# 元素既有字串又有數字 In [6]: systems = ['CentOs','Windows', 'Ubuntu', 666, ['MacOs']]#列表包含列表 In [7]: systems = ['CentOs','Windows', 'Ubuntu', 666, ['MacOs'],{'phone':'IOS'}]# 列表還可以包含字典
2.列表索引
列表中每個元素都會被分配一個數字,這個數字就是對應元素的位置,稱為索引。第一個元素的索引為0,第二個元素的索引為1,第三個元素的索引為2,依此類推。
注意:計算機中,幾乎所有的索引都是從0開始的,在涉及索引操作時,一定要注意這一點
通過索引訪問列表元素:
In [8]: systems = ['CentOs','Windows', 'Ubuntu'] In [9]: systems[0] Out[9]: 'CentOs' In [10]: systems[1] Out[10]: 'Windows' In [11]: systems[2] Out[11]: 'Ubuntu'
上面說到列表使用技巧靈活,是有道理的:可以使用 索引為-1 來直接獲取最後一個元素 ,也就是說,列表的索引可以倒著來:
In [12]: systems = ['CentOs','Windows', 'Ubuntu'] In [13]: systems[-1]# 直接獲取最後一個元素 Out[13]: 'Ubuntu' In [14]: systems[-2] Out[14]: 'Windows' In [15]: systems[-3] Out[15]: 'CentOs' In [16]: systems[-4]# 沒有索引-4,會丟擲超出範圍的異常 --------------------------------------------------------------------------- IndexErrorTraceback (most recent call last) <ipython-input-16-2b502eee5f42> in <module> ----> 1 systems[-4] IndexError: list index out of range
通過元素獲取索引:
In [17]: systems = ['CentOs','Windows', 'Ubuntu'] In [18]: systems.index('Windows') Out[18]: 1
3.列表切片
要說列表玩的6不6,就看切片熟不熟。切片其實就是一次性獲取多個元素:
In [19]: systems = ['CentOs','Windows', 'Ubuntu'] In [20]: systems[0:2] Out[20]: ['CentOs', 'Windows']
如上面程式碼所示,切片的操作為:列表[開始:結束:間隔] ,間隔預設為1,可以省略不寫。
注意:切片的兩個索引取左不取右,也就是是說,左閉右開
來看更靈活的使用方法:
In [21]: systems = ['CentOs','Windows', 'Ubuntu', 'IOS', 'Android'] In [22]: systems[2:5]# 獲取索引為2到5的元素,不包括5 Out[22]: ['Ubuntu', 'IOS', 'Android'] In [24]: systems[2:-1]# 獲取索引為2到-1的元素,不包括-1 Out[24]: ['Ubuntu', 'IOS'] In [25]: systems[0:5]# 獲取開頭元素到索引為5的元素,不包括5 Out[25]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android'] In [26]: systems[:5]# 從開頭取的話可以將0忽略,效果與上句一樣 Out[26]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android'] In [28]: systems[2:]# 結尾是列表的最後一個元素時,必須省略不寫,寫-1的話就取不到最後一個元素了 Out[28]: ['Ubuntu', 'IOS', 'Android'] In [29]: systems[:]# 獲取全部元素 Out[29]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android'] In [30]: systems[1:5:2]# 獲取索引為1到5的元素,並且每隔一個元素取一個,不包括5 Out[30]: ['Windows', 'IOS'] In [31]: systems[::2]# 從全部元素中每隔一個取一個 Out[31]: ['CentOs', 'Ubuntu', 'Android']
一定要熟練掌握上述方法
4.列表組合
列表相加:將不同的列表用 + 號加起來,效果如下:
In [32]: name1 = ['MinuteSheep','Mike'] In [33]: name2 = ['BigBan', 'Heenoor'] In [34]: name1 + name2 Out[34]: ['MinuteSheep', 'Mike', 'BigBan', 'Heenoor']
列表擴充套件:上面列表相加並沒有改變原有列表的元素,name1 + name2 是一個新的列表,可以傳給變數 name3;而列表的擴充套件將直接改變被擴充套件列表:
In [35]: name3 = name1 + name2# 將name1+name2傳給變數name3 In [36]: name3# 可以看到name3是一個新列表 Out[36]: ['MinuteSheep', 'Mike', 'BigBan', 'Heenoor'] In [37]: name1# name1列表並沒有被改變 Out[37]: ['MinuteSheep', 'Mike'] In [38]: name2# name2列表並沒有被改變 Out[38]: ['BigBan', 'Heenoor'] In [39]: name1.extend(name2)# 用name2擴充套件name1,使用extemd()方法 In [40]: name1# 可以看到name1列表被改變,因為name1是被擴充套件列表 Out[40]: ['MinuteSheep', 'Mike', 'BigBan', 'Heenoor'] In [41]: name2# name2列表並沒有被改變或者刪除 Out[41]: ['BigBan', 'Heenoor']
列表乘法:將一個列表與一個數字 n 相乘,得到一個 n 倍元素的新列表:
In [44]: systems Out[44]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android'] In [45]: systems * 3 Out[45]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android', 'CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android', 'CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android']
5.插入元素
追加:在列表末尾插入一個新的元素:
In [46]: systems Out[46]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android'] In [47]: systems.append('Unix')# 使用append()方法追加 In [48]: systems Out[48]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android', 'Unix']
任意位置插入:在列表的任意位置插入新元素,之前存在元素的位置向後加一:
In [48]: systems Out[48]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android', 'Unix'] In [49]: systems.insert(3,'Dos')# 使用 insert(位置,新元素名稱) 方法插入新元素 In [50]: systems Out[50]: ['CentOs', 'Windows', 'Ubuntu', 'Dos', 'IOS', 'Android', 'Unix']
6.修改列表
直接將被修改的元素重新賦值即可:
In [50]: systems Out[50]: ['CentOs', 'Windows', 'Ubuntu', 'Dos', 'IOS', 'Android', 'Unix'] In [51]: systems[3] Out[51]: 'Dos' In [52]: systems[3]= '我是之前的Dos,我被修改了'# 直接將被修改元素重新賦值即可 In [53]: systems Out[53]: ['CentOs', 'Windows', 'Ubuntu', '我是之前的Dos,我被修改了', 'IOS', 'Android', 'Unix']
7.刪除元素
刪除最後一個元素:將列表的末尾元素刪除:
In [53]: systems Out[53]: ['CentOs', 'Windows', 'Ubuntu', '我是之前的Dos,我被修改了', 'IOS', 'Android', 'Unix'] In [54]: systems.pop()# 使用pop()方法刪除末尾元素,並且返回末尾元素 Out[54]: 'Unix' In [55]: systems Out[55]: ['CentOs', 'Windows', 'Ubuntu', '我是之前的Dos,我被修改了', 'IOS', 'Android']
刪除任意位置元素:將列表中任意位置的元素刪除:
In [55]: systems Out[55]: ['CentOs', 'Windows', 'Ubuntu', '我是之前的Dos,我被修改了', 'IOS', 'Android'] In [56]: del systems[3]# 使用 del 命令刪除元素 In [57]: systems Out[57]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android']
刪除指定元素:刪除列表中指定的元素,不通過索引刪除,直接通過元素的名稱刪除:
In [57]: systems Out[57]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android'] In [58]: systems.remove('IOS')# 使用remove()方法刪除指定元素 In [59]: systems Out[59]: ['CentOs', 'Windows', 'Ubuntu', 'Android']
列表清空:將列表清空,列表依然存在,直是沒有元素而已,是一個空列表:
In [59]: systems Out[59]: ['CentOs', 'Windows', 'Ubuntu', 'Android'] In [60]: systems.clear()# 使用clear()方法將列表清空 In [61]: systems Out[61]: []
8.列表統計
統計列表長度:使用len()統計列表中元素的個數:
In [62]: systems = ['CentOs','Windows', 'Ubuntu', 'IOS', 'Android'] In [63]: len(systems)# 統計個數 Out[63]: 5
統計列表中某個元素的個數:使用count()方法統計指定元素的個數:
In [64]: systems = ['CentOs','Windows', 'Ubuntu', 'IOS', 'Android','IOS','Windows','IOS'] In [65]: systems.count('CentOs')# 使用count()方法計數 Out[65]: 1 In [66]: systems.count('IOS') Out[66]: 3
正排序:按照ASC碼進行從小到大的排序:
In [67]: systems Out[67]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android', 'IOS', 'Windows', 'IOS'] In [68]: systems.sort()# 使用sort()方法,從小到大排序 In [69]: systems Out[69]: ['Android', 'CentOs', 'IOS', 'IOS', 'IOS', 'Ubuntu', 'Windows', 'Windows']
逆排序:按照ASC碼進行從大到小的排序:
In [69]: systems Out[69]: ['Android', 'CentOs', 'IOS', 'IOS', 'IOS', 'Ubuntu', 'Windows', 'Windows'] In [70]: systems.reverse()#使用reverse()方法,從大到小排序 In [71]: systems Out[71]: ['Windows', 'Windows', 'Ubuntu', 'IOS', 'IOS', 'IOS', 'CentOs', 'Android']
注意:Python3中,列表例的資料型別一致才可以排序,否則會報錯
9.列表拷貝
關於列表的拷貝,有好多種方法,每一種方法都有差別,一起來看下:
方法1: b = a # a是一個列表
In [87]: a = [1,2,3] In [88]: b = a# 把a拷貝給b In [89]: id(a)# 可以看到a和b的地址相同,指向同一塊地址 Out[89]: 2762625492040 In [90]: id(b) Out[90]: 2762625492040 In [91]: a.append(5)# 列表a追加元素 In [92]: a Out[92]: [1, 2, 3, 5] In [93]: b# 列表b也改變了,還記得第五節在講變數時化的那個圖嗎? Out[93]: [1, 2, 3, 5]
方法二: b = a[:]
In [94]: a = [1,2,3] In [95]: b = a[:]# 把a列表拷貝給b In [96]: a.append(5) In [97]: a Out[97]: [1, 2, 3, 5] In [98]: b# 可以看到,b並沒有跟著改變 Out[98]: [1, 2, 3] In [99]: id(a)# 說明a和b指向不同的地址 Out[99]: 2762624748936 In [100]: id(b) Out[100]: 2762626722504
但是~~
In [107]: a = [1,2,[3]]# a列表裡面包含了一個新的列表 In [108]: b = a[:] In [109]: a[-1].append(5)# 子列表追繳一個新的元素 In [110]: a.append(6)# a列表追加一個新的元素 In [111]: a Out[111]: [1, 2, [3, 5], 6]# a變成了這樣 In [112]: b# 但是b的子列表卻跟著改變了,見鬼了! Out[112]: [1, 2, [3, 5]] In [113]: id(a)# a和b指向的地址並不一樣 Out[113]: 2762626869896 In [114]: id(b) Out[114]: 2762602977160
雖然b = a[:] 這種方式可以拷貝出一個新的列表,但是當列表中包含子列表的時候,拷貝出來的新列表中的子列表會跟著改變╮(╯▽╰)╭,應用的時候一定要注意吶
方式三: b = list(a)
In [115]: a = [1,2,3] In [116]: b = list(a) In [117]: a.append(5) In [118]: a Out[118]: [1, 2, 3, 5] In [119]: b Out[119]: [1, 2, 3] In [120]: a = [1,2,[3]] In [121]: b = list(a) In [122]: a[-1].append(5) In [123]: a.append(6) In [124]: a Out[124]: [1, 2, [3, 5], 6] In [125]: b Out[125]: [1, 2, [3, 5]] In [126]: id(a) Out[126]: 2762627298696 In [127]: id(b) Out[127]: 2762627301000
可以看到與方法二大同小異=====( ̄▽ ̄*)b
方法四: b = a * 1 # a為列表
In [128]: a = [1,2,3] In [129]: b = a * 1 In [130]: a.append(5) In [131]: a Out[131]: [1, 2, 3, 5] In [132]: b Out[132]: [1, 2, 3] In [133]: a = [1,2,[3]] In [134]: b = a * 1 In [135]: a[-1].append(5) In [136]: a.append(6) In [137]: a Out[137]: [1, 2, [3, 5], 6] In [138]: b Out[138]: [1, 2, [3, 5]] In [139]: id(a) Out[139]: 2762627326280 In [140]: id(b) Out[140]: 2762627611016
可以看到,與方法二、方法三大同小異,,ԾㅂԾ,,
方法五: b = a.copy() # a是列表
In [170]: a = [1,2,3] In [171]: b = a.copy() In [172]: a.append(5) In [173]: a Out[173]: [1, 2, 3, 5] In [174]: b Out[174]: [1, 2, 3] In [175]: a = [1,2,[3]] In [176]: b = a.copy() In [177]: a[-1].append(5) In [178]: a.append(6) In [179]: a Out[179]: [1, 2, [3, 5], 6] In [180]: b Out[180]: [1, 2, [3, 5]] In [181]: id(a) Out[181]: 2762628171912 In [182]: id(b) Out[182]: 2762628181320
可以看到,與方法二、方法三、方法四大同小異(ˉ▽ˉ;)...
方法六: b = copy.copy(a) # a為列表
In [141]: import copy# 需要匯入 copy 模組 In [142]: a = [1,2,3] In [143]: b = copy.copy(a) In [144]: a.append(5) In [145]: a Out[145]: [1, 2, 3, 5] In [146]: b Out[146]: [1, 2, 3] In [147]: a = [1,2,[3]] In [148]: b = copy.copy(a) In [149]: a[-1].append(5) In [150]: a.append(6) In [151]: a Out[151]: [1, 2, [3, 5], 6] In [152]: b Out[152]: [1, 2, [3, 5]] In [153]: id(a) Out[153]: 2762602926984 In [154]: id(b) Out[154]: 2762627609608
可以看到,與方法二、方法三、方法四、方法五大同小異(ˉ▽ˉ;)...
方法七: b = copy.deepcopy(a) # a為列表
In [155]: import copy In [156]: a = [1,2,3] In [157]: b = copy.deepcopy(a) In [158]: a.append(5) In [159]: a Out[159]: [1, 2, 3, 5] In [160]: b Out[160]: [1, 2, 3] In [161]: a = [1,2,[3]] In [162]: b = copy.deepcopy(a) In [163]: a[-1].append(5) In [164]: a.append(6) In [165]: a Out[165]: [1, 2, [3, 5], 6] In [166]: b# 這次b終於沒有被改變 Out[166]: [1, 2, [3]] In [167]: id(a) Out[167]: 2762627600712 In [168]: id(b) Out[168]: 2762625604936
哇~~這一次b列表終於沒有跟著改變ヾ(≧▽≦*)o
從以上七種方法可以看到,方法一最不推薦使用,方法二、方法三、方法四、方法五、方法六大同小異,都是複製列表後得到一個新的列表,但是一點列表中含有子列表,複製過來的列表中的子列表還是會跟著改變,方法七才會真正的做到完全複製且不是任何影響。
來一個列表的總結:
a.append(x)# 列表a追加元素x a.clear()# 將列表a清空 a.copy()# 拷貝列表a a.count(x)# 對a列表的元素x計數 a.extend(b)# 把b列表擴充套件到a列表中 a.index(x)# 查詢a列表中x元素的索引 a.insert(n,x)# 在列表a的第n個位置處插入元素x a.pop()# 將列表a的末尾元素刪除,並返回這個元素 a.remove(x)# 將列表a的元素x刪除 a.reverse()# 按ASC碼進行從大到小的排序 a.sort()# 按ASC碼進行從小到大的排序
二、元組
元組與列表相似,只不過元組不能修改其內部元素。列表使用方括號,而元組使用圓括號。
In [193]: dir(tuple) Out[193]: ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
可以看到,元組的方法少的可憐,只有 count 和 index 方法
1.初始化元組
與列表類似,用一對圓括號括起來,元素之間用逗號分隔開,需要注意的是元組最後一定要加逗號 :
In [184]: systems = ('Linux', 'Windows', 'Unix',) In [185]: systems = ('Linux', 'Windows', 'Unix', 666,) In [186]: systems = ('Linux', 'Windows', 'Unix', 666, [1, 3,5],) In [187]: systems = ('Linux', 'Windows', 'Unix', 666, [1, 3,5], (2,4,6),) In [188]: systems = ('Linux', 'Windows', 'Unix', 666, [1, 3,5], (2,4,6), {'a':250},) # 與列表極為相似
2.元組索引
同列表一樣
In [189]: systems = ('Linux', 'Windows', 'Unix',) In [190]: systems[1] Out[190]: 'Windows'
3.元組切片
同列表一樣
In [191]: systems = ('Linux', 'Windows', 'Unix',) In [192]: systems[2:] Out[192]: ('Unix',)
4.元組組合
同列表一樣
In [194]: systems Out[194]: ('Linux', 'Windows', 'Unix',) In [197]: systems1 = ('IOS',) In [198]: systems + systems1 Out[198]: ('Linux', 'Windows', 'Unix', 'IOS',) In [200]: systems * 3 Out[200]: ('Linux', 'Windows', 'Unix', 'Linux', 'Windows', 'Unix', 'Linux', 'Windows', 'Unix',)
5.元組統計
同列表一樣
In [202]: systems = ('Linux', 'Windows', 'Unix',) In [203]: systems.count('Linux') Out[203]: 1 In [204]: len(systems) Out[204]: 3
元組就這麼多o_o ....