Python初学小知识(三):列表List
C语言和Python经常弄混,尤其总是忍不住给Python后面加分号……干脆给自己做个笔记省的忘了。。。(小甲鱼那边的)
七、列表List
1. 列表同时包含多种数据类型,下标索引从0开始,最后一个元素的下标索引值是-1,以此类推,倒数第二个是-2:
>>> word = [10,5,'you',0.1]
>>> for i in word:
print(i)
10
5
you
0.1
>>> word[1]
5
>>> word[-2]
'you'
2. 列表切片,打印的是下标对应的值,不包括最后一个
>>> word[1:3]
[5, 'you']
>>> word[:2] #从头开始没必要把头写进去
[10, 5]
>>> word[2:] #一直到结尾没必要把尾写进去
['you', 0.1]
>>> word[:]
[10, 5, 'you', 0.1]
>>> word[0:4:2] #跨进
[10, 'you']
>>> word[::2] #跨进
[10, 'you']
>>> word[::-1] #倒序输出
[0.1, 'you', 5, 10]
3. 列表的增删改查
3.1 增
'''append与extend'''
>>> heros = ['钢铁侠','绿巨人']
>>> heros.append('黑寡妇') #只能添加一个对象
>>> heros
['钢铁侠', '绿巨人', '黑寡妇']
>>> heros.extend(['鹰眼','灭霸','雷神']) #添加可迭代对象
>>> heros
['钢铁侠', '绿巨人', '黑寡妇', '鹰眼', '灭霸', '雷神']
'''还可以使用切片的方式增加'''
>>> s = [1,'a',2,'d']
>>> s[len(s):] = [4,'add']
>>> s
[1, 'a', 2, 'd', 4, 'add']
>>> s[1:3] = [344,87] #用切片替换了原有的s[1:3]
>>> s
[1, 344, 87, 'd', 4, 'add']
'''在指定位置insert插入'''
>>> s.insert(1,'boy') #insert(位置,元素)
>>> s
[1, 'boy', 344, 87, 'd', 4, 'add']
3.2 删
'''remove删除指定元素:如果列表中存在多个匹配的元素,只会删除第一个'''
>>> heros = ['钢铁侠', '绿巨人', '黑寡妇', '鹰眼', '灭霸', '雷神']
>>> heros.remove('灭霸')
>>> heros
['钢铁侠', '绿巨人', '黑寡妇', '鹰眼', '雷神']
'''pop(下标)删除指定位置的元素'''
>>> heros.pop(2)
'黑寡妇'
>>> heros
['钢铁侠', '绿巨人', '鹰眼', '雷神']
'''clear()清空列表'''
>>> heros.clear()
>>> heros
[]
3.3 改
>>> heros = ['钢铁侠', '绿巨人', '黑寡妇', '鹰眼', '灭霸', '雷神']
>>> heros[4] = '钢铁侠'
>>> heros
['钢铁侠', '绿巨人', '黑寡妇', '鹰眼', '钢铁侠', '雷神']
>>> heros[3:] = ['武松','林冲','李逵']
>>> heros
['钢铁侠', '绿巨人', '黑寡妇', '武松', '林冲', '李逵']
'''sort()从小到大排序,sort(key=None, reverse=False),key用于指定一个比较的函数,reverse用于指定排序结果是否反转'''
>>> num = [3,2,6,3,8,9,6,4,1,55]
>>> num.sort()
>>> num
[1, 2, 3, 3, 4, 6, 6, 8, 9, 55]
'''reverse()从大到小排序'''
>>> num.reverse()
>>> num
[55, 9, 8, 6, 6, 4, 3, 3, 2, 1]
#但是,如果是初始的num列表,结果是这样:
>>> num = [3,2,6,3,8,9,6,4,1,55]
>>> num.reverse()
>>> num
[55, 1, 4, 6, 9, 8, 3, 6, 2, 3]
#reverse()其实是原地反转函数,并不是真的从大到小排序,所以包含字符串的列表也可以用reverse:
>>> heros.reverse()
>>> heros
['李逵', '林冲', '武松', '黑寡妇', '绿巨人', '钢铁侠']
3.4 查
'''count()查找列表中某个元素出现的次数(包括数字、字符串)'''
>>> num = [3,2,6,3,8,9,6,4,1,55]
>>> num.count(3)
2
>>> heros = ['钢铁侠', '绿巨人', '黑寡妇', '鹰眼', '钢铁侠', '雷神']
>>> heros.count('钢铁侠')
2
'''index(x, start, end)查找元素索引值'''
>>> heros.index('钢铁侠')
0 #有多个元素的,只出现第一个元素的索引值
>>> heros.index('绿巨人')
1
>>> heros[heros.index('钢铁侠')] = '神奇女侠'
>>> heros
['神奇女侠', '绿巨人', '黑寡妇', '鹰眼', '钢铁侠', '雷神']
#通过利用索引值替换元素,有多个元素时,只操作第一个
>>> num.index(3,1,20) #end超出了列表长度也没关系
3
'''copy()拷贝列表'''
>>> num_copy1 = num.copy()
>>> num_copy1
[3, 2, 6, 3, 8, 9, 6, 4, 1, 55]
>>> num.pop(-1)
55
>>> num
[3, 2, 6, 3, 8, 9, 6, 4, 1]
>>> num_copy1
[3, 2, 6, 3, 8, 9, 6, 4, 1, 55]
>>> num_copy2 = num[:]
>>> num_copy2
[3, 2, 6, 3, 8, 9, 6, 4, 1]
>>>
4. 列表的加法和乘法
>>> s = [1,2,3]
>>> t = [4,5,6]
>>> s + t #加法是拼接
[1, 2, 3, 4, 5, 6]
>>> s * 3 #乘法是重复
[1, 2, 3, 1, 2, 3, 1, 2, 3]
5. 列表的嵌套
>>> matrix = [[1,2,3],[4,5,6],[7,8,9]]
>>> matrix = [[1,2,3],
[4,5,6],
[7,8,9]]
>>> matrix
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
'''访问嵌套列表:'''
>>> for i in matrix:
for j in i:
print(j,end='')
print()
123
456
789
>>> for i in matrix:
for j in i:
print(j,end=' ') #end=''的单引号中间如果加了空格,那么打印出来的才会有空格
print()
1 2 3
4 5 6
7 8 9
>>> matrix[0] #下标访问嵌套列表
[1, 2, 3]
>>> matrix[0][0]
1
>>> A = [0] * 4
>>> for i in range(2):
A[i] = [1] * 2
>>> A
[[1, 1], [1, 1], 0, 0]
6. python对于不同的对象,存储机制是不一样的
>>> x = 'abc'
>>> y = 'abc'
>>> x is y
True #字符串可以相等
>>> x = [1,2,3]
>>> y = [1,2,3]
>>> x is y
False #列表就不行
python中的赋值并不是放入一个盒子中,而是引用,如果我们改变上面的x,则y也会跟着改变;如果想得到两个独立的列表,应该用拷贝。
7. 拷贝分为浅拷贝和深拷贝
'''浅拷贝就是copy或者切片'''
#copy
>>> x = [1,2,3]
>>> y = x.copy()
>>> x[1] = 1
>>> x
[1, 1, 3]
>>> y
[1, 2, 3]
#切片
>>> x = [1,2,3]
>>> y = x[:]
>>> x[1] = 1
>>> x
[1, 1, 3]
>>> y
[1, 2, 3]
但是浅拷贝无法作用在嵌套列表上:
>>> x = [[1,2,3],[4,5,6],[7,8,9]]
>>> y = x.copy()
>>> x[1][1] = 0
>>> x
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>> y
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
copy之后,改变了x里面的内容,y一样改变,因为浅拷贝只是拷贝了外层的对象。
于是使用深拷贝来解决这个问题:
>>> import copy
>>> x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> y = copy.copy(x) #前一个copy表示copy模块,后一个copy表示copy函数
>>> x[1][1] = 0
>>> x
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>> y
[[1, 2, 3], [4, 0, 6], [7, 8, 9]] #以上的还是浅拷贝
'''深拷贝deepcopy'''
>>> x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> y = copy.deepcopy(x)
>>> x[1][1] = 0
>>> x
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>> y
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
但是还是用浅拷贝更多,因为效率更高。
8. 列表推导式: [expression for target in intrable]
如果想把列表中的元素×2,怎么做?
>>> x = [1,2,3,4,5]
>>> for i in range(len(x)):
x[i] = x[i] * 2
>>> x
[2, 4, 6, 8, 10]
如果用列表推导式:
>>> x = [1,2,3,4,5]
>>> x = [i * 2 for i in x]
>>> x
[2, 4, 6, 8, 10]
通常列表推导式的效率比循环语句要快上一倍左右:因为列表推导式在python中是用C语言执行的,比使用python脚本的虚拟机pym里面以步进的速度来运行for循环要快得多。
8.1 列表推导式: [expression for target in intrable]
>>> x = [i for i in range(10)]
>>> x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#把i换成i+1就可以得到1到10
'''字符串同理'''
>>> y = [i * 2 for i in 'nxy']
>>> y
['nn', 'xx', 'yy']
'''把字符转换成对应的Unicode编码'''
>>> code = [ord(i) for i in 'nxy']
>>> code
[110, 120, 121]
'''提取二维列表某一列的元素'''
>>> matrix = [[1,2,3],
[4,5,6],
[7,8,9]]
>>> col2 = [row[1] for row in matrix] #提取第二列
#通过row语句提取matrix里面的每一行,存放的是row[1]
>>> col2
[2, 5, 8]
'''获取主对角线元素'''
>>> diag = [matrix[i][i] for i in range(len(matrix))] #获取i是1,2,3
>>> diag
[1, 5, 9]
如果是右对角线?
循环是通过迭代来修改原列表中的元素,而列表推导式是直接创建一个新的列表然后赋值为原先的变量名。
利用循环来创建一个嵌套列表:
>>> for i in range(3):
A[i] = [1] * 2
>>> A
[[1, 1], [1, 1], [1, 1]]
>>> A[0][1] = 0
>>> A
[[1, 0], [1, 1], [1, 1]]
利用列表推导式来创建一个嵌套列表:
>>> S = [[1] * 2 for i in range(3)]
>>> S
[[1, 1], [1, 1], [1, 1]]
>>> S[0][1] = 0
>>> S
[[1, 0], [1, 1], [1, 1]]
8.2 添加用于筛选的if分句:[expression for target in intrable if condition]
>>> even = [i for i in range(10) if i % 2 == 0]
>>> even
[0, 2, 4, 6, 8]
>>> even = [i + 1 for i in range(10) if i % 2 == 0]
>>> even
[1, 3, 5, 7, 9] #把上面的结果都+1→i+1
'''先执行for语句,再执行if语句,最后才是左侧的表达式'''
>>> word = ['agg', 'boy', 'cat', 'dog', 'apple', 'and']
>>> a_in = [i for i in word if 'a' in i]
>>> a_in
['agg', 'cat', 'apple', 'and'] #含有a的单词
>>> a_begin = [i for i in word if 'a' in i[0]]
>>> a_begin
['agg', 'apple', 'and'] #a开头的单词,也可以if 'a' == i[0]
8.3 列表推导式还可以用来嵌套
[expression for target1 in intrable1
for target2 in intrable2
……
for targetN in intrableN]**
嵌套的外层循环放前面。
>>> matrix = [[1,2,3], [4,5,6], [7,8,9]]
>>> fold = []
>>> for a in matrix: #取出来matrix里面的元素,即[1,2,3], [4,5,6], [7,8,9]
for b in a:
fold.append(b)
print(fold)
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
8.4 最后发展出的终极语法
[expression for target1 in intrable1 if condition1
for target2 in intrable2 if condition2
……
for targetN in intrableN if conditionN]**
>>> [[x,y] for x in range(6) if x % 2 == 0 for y in range(9) if y % 3 == 0]
[[0, 0], [0, 3], [0, 6], [2, 0], [2, 3], [2, 6], [4, 0], [4, 3], [4, 6]]
但是不必为了炫耀搞得过于复杂