列表相关
1.两个列表相加会得到一个新的列表
a = [1, 2, 3, 4] b = [5, 6] c = a + b print(c) #c=[1, 2, 3, 4, 5, 6] a[0] = 100 print(c) #c = [1, 2, 3, 4, 5, 6] 因为两个列表a、b相加,会等到一个新的列表,然后将c指向这个新的列表。所以a列表的改变不会影响c列表
2.对列表来说,a+=b和a=a+b不同
b = a = [1, 2] a += [3] #a += [3]是在a列表里追加3 print(a, b) #[1, 2, 3] [1, 2, 3] a = a + [4, 5] #a = a + [4, 5] 是生成了一个新的列表[1, 2, 3, 4, 5],然后让a指向这个新的列表 print(a) #[1, 2, 3, 4, 5] print(b) #[1, 2, 3]
3.理解列表例题
a = [[0]]*2 + [[0]]*2 a[0][0] = 5 print(a)
A [5, 0, 0, 0]
B [5, 5, 5, 5]
C [[5], [5], [0], [0]]
D [[5], [5], [5], [5]]
分析:
第一条语句:a = [[0]]*2 + [[0]]*2 是先申请了一个列表[0],再执行[[0]]*2操作,得到列表[[0], [0]];接下来在内存中申请一个列表[0](这个列表[0]和前面的列表[0],不是同一个列表,因为列表是可变对象),得到列表[[0], [0]];最后两个[[0], [0]]相加,得到[[0], [0], [0], [0]]
第二条语句:a[0][0] = 5,将第一个列表[[0]]中的0改为5 ,故第一个列表执行*2,变为[[5],[5]]。最后选C
最终效果为:
4.列表的排序
列表排序有sort()和sorted()两个方法,sort()方法会改变列表本身,sorted()方法会生成一个新的列表,不会改变列表本身
# 列表的排序 a = [5, 7, 6, 3, 4, 1, 2] a.sort() # sort()方法,会改变列表a print(a) a = [5, 7, 6, 3, 4, 1, 2] b = sorted(a) # sorted()方法不会改变列表a,会返回一个新的列表 print(a) a = [25, 7, 16, 33, 4, 1, 2] a.sort(reverse=True) print(a) a = [25, 7, 16, 33, 4, 1, 2] b = sorted(a, reverse=True) print(a) print(b)
5.列表的自定义排序
# 自定义排序 def mykey(x): return x % 10 a = [25, 7, 16, 33, 4, 1, 2] a.sort(key=mykey) print(a) # a = [1, 2, 33, 4, 25, 16, 7]
b = sorted('This is a test string from Andrew'.split(), key=str.lower) print(b)
students = [ ('John', 'A', 15), ('Mike', 'C', 19), ('Mike', 'B', 12), ('Mike', 'C', 18), ('Bom', 'D', 10), ] students.sort(key=lambda x: x[2]) # lambda表达式,实际上就是一个函数,x为输入,x[2]为输出 print(students)
students = [ ('John', 'A', 15), ('Mike', 'C', 19), ('Mike', 'B', 12), ('Mike', 'C', 18), ('Bom', 'D', 10), ] students.sort(key=lambda x: x[0]) print(students) #python排序算法为稳定排序算法(以前在前面的依然在前面,在后面的依然在后面)
6.元组不能修改,所以不能用sort()排序,但可以用sorted()排序,排序之后得到的是列表
def f(x): return (-x[2], x[1], x[0]) students = ( ('John', 'A', 15), ('Mike', 'C', 19), ('Wang', 'B', 12), ('Mike', 'B', 12), ('Mike', 'C', 18), ('Mike', 'C', 18), ('Bom', 'D', 10), ) # students是元组 print(sorted(students, key=f)) # 排序后是列表
7.列表的函数
# 列表函数 a, b = [1, 2, 3], [5, 6] a.append(b) print(a) b.insert(1, 100) print(a) a.extend(b) # extend()相当于+= print(a) a.insert(1, 'k') a.insert(3, 'k') print(a) a.remove('k') print(a) a.reverse() print(a) print(a.index('k')) try: print(a.index('m')) except Exception as e: print(e)
8.列表的映射和过滤
map(function, sequence),可用于将一个序列(列表、元组、集合。。。)映射到另一个序列
返回一个延时求值对象,可以转换成list、tuple、set
# 列表的映射返回一个延时求值对象,并把返回结果收集起来 def f(x): print(x, end="") return x*x a = map(f, [1, 2, 3]) print(list(a)) # 123[1, 4, 9] print(tuple(a)) # () a = list(map(lambda x: 2*x, [2, 3, 4])) print(a) # [4, 6, 8]
map可以用于输入:
a, b = map(int, input().split()) # 此处tuple省略
filter(function, sequence),抽取数列中令function(x)为True的元素x
返回一个延时求值对象,可以转换成list、tuple、set
# 列表过滤 def f(x): if x%2 == 0: return x # return x%2 == 0 lst = tuple(filter(f, [1, 2, 3, 4, 5])) print(lst)
9. 列表生成式(列表推倒式)
print([x*x for x in range(1, 11)]) print([x*x for x in range(1, 11) if x%2==0]) print([m+n for m in 'ABC' for n in 'XYZ']) # ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ'] l = [[m+n for m in 'ABC'] for n in 'XYZ'] # [['AX', 'BX', 'CX'], ['AY', 'BY', 'CY'], ['AZ', 'BZ', 'CZ']] print(l) L = ['Hello', 'World', 18, 'Apple', None] l = [s.lower() for s in L if isinstance(s, str) ] print(l) l = [s for s in L if isinstance(s, int) ] print(l) # 元组列表生成式,必须有tuple,不然返回的是地址 print(tuple( x*x for x in range(1,11)))
10.二维列表
二维列表可以看成矩阵,a[i][j]就是第i行第j列的元素
# 错误生成二维列表的方法 a = [0, 0, 0] b = [a] * 3 print(b) # b = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] b[0][1] = 1 a[2] = 100 print(b) # b = [[0, 1, 100], [0, 1, 100], [0, 1, 100]] 修改b[0][1],b[1][1]和b[2][1]也改变了。因为b中的每个列表和a都指向同一地址
# 定义二维列表 # 二维列表本质上还是列表,列表中的列表指向内存中不同的地方 matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] print(matrix) print(matrix[1][2], matrix[2][2]) matrix[1][1] = 100 print(matrix)
用列表推导式定义二维列表
# 列表推导式初始化矩阵 matrix = [[0 for i in range(3)] for i in range(3)] print(matrix) matrix = [[i*3+j for j in range(3)] for i in range(3)] print(matrix)
生成一个三行四列的二维列表,并初始化
# 生成一个3行4列的矩阵,所有元素都是0 lst = [] for i in range(3): lst.append([0]*4) lst[0][0] = lst[2][3] = 100 for i in range(3): for j in range(4): print(lst[i][j], end=" ") print("")
定义二维元组
# 二维元组 matrix = ((1, 2, 3), (4, 5, 6), (7, 8, 9)) print(matrix) matrix = tuple(tuple(0 for i in range(3)) for i in range(3)) print(matrix)
11.列表的拷贝
浅拷贝:拷贝指针(地址)
深拷贝:实现值的拷贝(两个列表完全分割,修改一个不会影响另一个)
# 列表的浅拷贝 a = [1, 2, 3, 4] b = a[:] # b是a的拷贝,b和a不是同一个对象,指向不同的东西。 b=a是指针的拷贝,b和a指向同一内存地址 b[0] = 5 print(a) # a = [1, 2, 3, 4] 对b的修改不会影响a b += [10] print(a) # a = [1, 2, 3, 4] 对b的修改不会影响a
列表浅拷贝存在的问题:当列表中有列表时,做不到完全分割
# 列表浅拷贝的问题 # 列表的浅拷贝只是拷贝的指针(地址) a = [1, [2]] b = a[:] b.append(4) print(b) # b = [1, [2], 4] a[1].append(3) print(a) # a = [1, [2,3]] 此处对列表a进行了修改 print(b) # b = [1, [2,3], 4] 影响了列表b,因为b[2]和a[2]指向的是同一内存地址
列表的深拷贝
# 列表的深拷贝 import copy a = [1, [2]] b = copy.deepcopy(a) b.append(4) print(b) # b = [1, [2], 4] a[1].append(3) print(a) # a = [1, [2, 3]] 此处对a进行了修改 print(b) # b = [1, [2], 4] a的修改未对b产生影响