#9 Python列表和元组
Python中有6种序列:列表、元组、字符串、Unicode字符串、buffer对象和xrange对象。序列通用操作包括:索引、切片、长度、加、乘、最大值、最小值,遍历和检查成员。虽然Python有6中内置序列,但是最常用的是列表和元组。所以本博文将深入列表和元组,掌握其方法!
一、列表(list)
看了上面说的,现在是不是一头雾水,其实上面提到的操作无非不过一些方法而已,熟练应用就掌握了,那先来看看列表的方法吧:
1 2 3
   | 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 2 3 4 5 6 7
   | 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'}]   
   | 
 
列表索引
列表中每个元素都会被分配一个数字,这个数字就是对应元素的位置,称为索引。第一个元素的索引为0,第二个元素的索引为1,第三个元素的索引为2,依此类推。
注意:计算机中,几乎所有的索引都是从0开始的,在涉及索引操作时,一定要注意这一点
通过索引访问列表元素:
1 2 3 4 5 6 7 8 9 10
   | 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 来直接获取最后一个元素,也就是说,列表的索引可以倒着来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | 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]      --------------------------------------------------------------------------- IndexError                                Traceback (most recent call last) <ipython-input-16-2b502eee5f42> in <module> ----> 1 systems[-4]
  IndexError: list index out of range
   | 
 
通过元素获取索引:
1 2 3 4
   | In [17]: systems = ['CentOs','Windows', 'Ubuntu']
  In [18]: systems.index('Windows') Out[18]: 1
   | 
 
列表切片
要说列表玩的6不6,就看切片熟不熟。切片其实就是一次性获取多个元素:
1 2 3 4
   | In [19]: systems = ['CentOs','Windows', 'Ubuntu']
  In [20]: systems[0:2] Out[20]: ['CentOs', 'Windows']
   | 
 
如上面代码所示,切片的操作为:列表[开始:结束:间隔] ,间隔默认为1,可以省略不写。
注意:切片的两个索引取左不取右,也就是是说,左闭右开
来看更灵活的使用方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   | In [21]: systems = ['CentOs','Windows', 'Ubuntu', 'IOS', 'Android']
  In [22]: systems[2:5]           Out[22]: ['Ubuntu', 'IOS', 'Android']
 
  In [24]: systems[2:-1]          Out[24]: ['Ubuntu', 'IOS']
  In [25]: systems[0:5]           Out[25]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android']
  In [26]: systems[:5]            Out[26]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android']
  In [28]: systems[2:]            Out[28]: ['Ubuntu', 'IOS', 'Android']
  In [29]: systems[:]             Out[29]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android']
  In [30]: systems[1:5:2]         Out[30]: ['Windows', 'IOS']
  In [31]: systems[::2]           Out[31]: ['CentOs', 'Ubuntu', 'Android']
   | 
 
一定要熟练掌握上述方法
列表组合
列表相加:将不同的列表用 + 号加起来,效果如下:
1 2 3 4 5 6
   | In [32]: name1 = ['MinuteSheep','Mike']
  In [33]: name2 = ['BigBan', 'Heenoor']
  In [34]: name1 + name2 Out[34]: ['MinuteSheep', 'Mike', 'BigBan', 'Heenoor']
   | 
 
列表扩展:上面列表相加并没有改变原有列表的元素,name1 + name2 是一个新的列表,可以传给变量 name3;而列表的扩展将直接改变被扩展列表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | In [35]: name3 = name1 + name2   
  In [36]: name3                    Out[36]: ['MinuteSheep', 'Mike', 'BigBan', 'Heenoor']
  In [37]: name1                    Out[37]: ['MinuteSheep', 'Mike']
  In [38]: name2                    Out[38]: ['BigBan', 'Heenoor']
  In [39]: name1.extend(name2)     
  In [40]: name1                    Out[40]: ['MinuteSheep', 'Mike', 'BigBan', 'Heenoor']
  In [41]: name2                    Out[41]: ['BigBan', 'Heenoor']
   | 
 
列表乘法:将一个列表与一个数字 n 相乘,得到一个 n 倍元素的新列表:
1 2 3 4 5 6
   | 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']
   | 
 
插入元素
追加:在列表末尾插入一个新的元素:
1 2 3 4 5 6 7
   | In [46]: systems Out[46]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android']
  In [47]: systems.append('Unix')      
  In [48]: systems Out[48]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android', 'Unix']
   | 
 
任意位置插入:在列表的任意位置插入新元素,之前存在元素的位置向后加一:
1 2 3 4 5 6 7
   | In [48]: systems Out[48]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android', 'Unix']
  In [49]: systems.insert(3,'Dos')     
  In [50]: systems Out[50]: ['CentOs', 'Windows', 'Ubuntu', 'Dos', 'IOS', 'Android', 'Unix']
   | 
 
修改列表
直接将被修改的元素重新赋值即可: 1 2 3 4 5 6 7 8 9 10
   | 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']
   | 
删除元素
删除最后一个元素:将列表的末尾元素删除:
1 2 3 4 5 6 7 8
   | In [53]: systems Out[53]: ['CentOs', 'Windows', 'Ubuntu', '我是之前的Dos,我被修改了', 'IOS', 'Android', 'Unix']
  In [54]: systems.pop()       Out[54]: 'Unix'
  In [55]: systems Out[55]: ['CentOs', 'Windows', 'Ubuntu', '我是之前的Dos,我被修改了', 'IOS', 'Android']
   | 
 
删除任意位置元素:将列表中任意位置的元素删除:
1 2 3 4 5 6 7
   | In [55]: systems Out[55]: ['CentOs', 'Windows', 'Ubuntu', '我是之前的Dos,我被修改了', 'IOS', 'Android']
  In [56]: del systems[3]     
  In [57]: systems Out[57]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android']
   | 
 
删除指定元素:删除列表中指定的元素,不通过索引删除,直接通过元素的名称删除:
1 2 3 4 5 6 7
   | In [57]: systems Out[57]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android']
  In [58]: systems.remove('IOS')   
  In [59]: systems Out[59]: ['CentOs', 'Windows', 'Ubuntu', 'Android']
   | 
 
列表清空:将列表清空,列表依然存在,直是没有元素而已,是一个空列表:
1 2 3 4 5 6 7
   | In [59]: systems Out[59]: ['CentOs', 'Windows', 'Ubuntu', 'Android']
  In [60]: systems.clear()        
  In [61]: systems Out[61]: []
   | 
 
列表统计
统计列表长度:使用len()统计列表中元素的个数:
1 2 3 4
   | In [62]: systems = ['CentOs','Windows', 'Ubuntu', 'IOS', 'Android']
  In [63]: len(systems)    Out[63]: 5
   | 
 
统计列表中某个元素的个数:使用count()方法统计指定元素的个数:
1 2 3 4 5 6 7
   | In [64]: systems = ['CentOs','Windows', 'Ubuntu', 'IOS', 'Android','IOS','Windows','IOS']
  In [65]: systems.count('CentOs')    Out[65]: 1
  In [66]: systems.count('IOS') Out[66]: 3
   | 
 
正排序:按照ASC码进行从小到大的排序:
1 2 3 4 5 6 7
   | In [67]: systems Out[67]: ['CentOs', 'Windows', 'Ubuntu', 'IOS', 'Android', 'IOS', 'Windows', 'IOS']
  In [68]: systems.sort()   
  In [69]: systems Out[69]: ['Android', 'CentOs', 'IOS', 'IOS', 'IOS', 'Ubuntu', 'Windows', 'Windows']
   | 
 
逆排序:按照ASC码进行从大到小的排序:
1 2 3 4 5 6 7
   | In [69]: systems Out[69]: ['Android', 'CentOs', 'IOS', 'IOS', 'IOS', 'Ubuntu', 'Windows', 'Windows']
  In [70]: systems.reverse()   
  In [71]: systems Out[71]: ['Windows', 'Windows', 'Ubuntu', 'IOS', 'IOS', 'IOS', 'CentOs', 'Android']
   | 
 
注意:Python3中,列表例的数据类型一致才可以排序,否则会报错
列表拷贝
关于列表的拷贝,有好多种方法,每一种方法都有差别,一起来看下:
方法1: b = a   # a是一个列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | In [87]: a = [1,2,3]
  In [88]: b = a             In [89]: id(a)          Out[89]: 2762625492040
  In [90]: id(b) Out[90]: 2762625492040
  In [91]: a.append(5)   
  In [92]: a Out[92]: [1, 2, 3, 5]
  In [93]: b              Out[93]: [1, 2, 3, 5]
   | 
 
方法二: b = a[:]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | In [94]: a = [1,2,3]
  In [95]: b = a[:]   
  In [96]: a.append(5)
  In [97]: a Out[97]: [1, 2, 3, 5]
  In [98]: b           Out[98]: [1, 2, 3]
  In [99]: id(a)       Out[99]: 2762624748936
  In [100]: id(b) Out[100]: 2762626722504
   | 
 
但是~~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | In [107]: a = [1,2,[3]]        
  In [108]: b = a[:]
  In [109]: a[-1].append(5)      
  In [110]: a.append(6)          
  In [111]: a Out[111]: [1, 2, [3, 5], 6]    
  In [112]: b                     Out[112]: [1, 2, [3, 5]]
  In [113]: id(a)                 Out[113]: 2762626869896
  In [114]: id(b) Out[114]: 2762602977160
   | 
 
虽然b = a[:] 这种方式可以拷贝出一个新的列表,但是当列表中包含子列表的时候,拷贝出来的新列表中的子列表会跟着改变╮(╯▽╰)╭,应用的时候一定要注意呐
方式三: b = list(a)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
   | 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为列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
   | 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是列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
   | 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为列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
   | In [141]: import 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为列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
   | 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                  Out[166]: [1, 2, [3]]
  In [167]: id(a) Out[167]: 2762627600712
  In [168]: id(b) Out[168]: 2762625604936
   | 
 
哇~~这一次b列表终于没有跟着改变ヾ(≧▽≦)o
从以上七种方法可以看到,方法一最不推荐使用,方法二、方法三、方法四、方法五、方法六大同小异,都是复制列表后得到一个新的列表,但是一但列表中含有子列表,复制过来的列表中的子列表还是会跟着改变,方法七才会真正的做到完全复制且不是任何影响。
来一个列表的总结:
1 2 3 4 5 6 7 8 9 10 11
   | a.append(x)               a.clear()                 a.copy()                  a.count(x)                a.extend(b)               a.index(x)                a.insert(n,x)             a.pop()                   a.remove(x)               a.reverse()               a.sort()                 
   | 
 
二、元组
元组与列表相似,只不过元组不能修改其内部元素。列表使用方括号,而元组使用圆括号。
1 2 3
   | 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 2 3 4 5 6 7 8 9 10 11
   | 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},)
 
 
  | 
 
元组索引
同列表一样
1 2 3 4
   | In [189]: systems = ('Linux', 'Windows', 'Unix',)   
  In [190]: systems[1] Out[190]: 'Windows'
  | 
 
元组切片
同列表一样
1 2 3 4
   | In [191]: systems = ('Linux', 'Windows', 'Unix',)
  In [192]: systems[2:] Out[192]: ('Unix',)
  | 
 
元组组合
同列表一样
1 2 3 4 5 6 7 8 9 10 11 12
   | 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',)
   | 
 
元组统计
同列表一样
1 2 3 4 5 6
   | In [202]: systems = ('Linux', 'Windows', 'Unix',)
  In [203]: systems.count('Linux') Out[203]: 1 In [204]: len(systems) Out[204]: 3
  | 
 
元组就这么多o_o ....