数据类型详解-列表
列表就是一组有序的数据组合,列表中的数据可以被修改
1. 列表的定义
- 可以使用 中括号进行定义 []
- 也可以使用 list函数 定义
- 在定义列表中的元素时,需要在每个元素之间使用逗号,进行分隔。[1,2,3,4]
- 列表中的元素可以是任意类型的,通常用于存放同类项目的集合
2. 列表的基本操作
-
列表定义-[],list()
-
列表相加-拼接:直接用+号,print(a + b + [11,22])
-
列表相乘-重复:print(a*3) >>>[1,2,1,2,1,2]
注意!只能乘数字
-
列表的下标- 获取,更新
print(a[1]) #获取,也可以用倒数的下标 a[1] = 3 #更新,但是不能通过下标添加元素
-
列表元素的添加-append():在列表的最后添加
-
列表元素的删除
- del 列表[下标]
a = [1,2,3] del a[1] print(a) >>>[1,3]
- pop()函数 删除元素
a = [1,2,3] print(a.pop()) #删除最后一个 print(a.pop(0))#删除指定索引 >>>3 1
3. 列表的切片:和字符串的操作一样
list[start:结束:step]
-
列表[开始索引:] ==> 从开始索引到列表的最后
-
列表[:结束值] ==> 从开始到指定的结束索引之前
-
列表[开始索引:结束索引] ==> 从开始索引到指定结束索引之前
-
列表[开始索引:结束索引:步进值] ==> 从指定索引开始到指定索引前结束,按照指定步进进行取值切片
-
列表[:] 或 列表[::] ==> 所有列表元素的切片
a = [1,2,3]
print(a[:]) 等于 print(a[::]) 等于 print(a)
#注意!print(a[])是错的!
-
列表[::-1] ==> 倒着获取列表的元素
【和字符串一样,倒过来时候,开始索引和结束索引也要倒过来】 a = [1,2,3] print(a[5:0:-1]) >>>[3, 2] 【超出列表范围不会报错,此时也遵循左闭右开,取不到索引为0的元素】
-
列表的切片更新:list[开始:结束:步进] = [(这里是对应的元素)]
# 从指定下标开始,到指定下标前结束,并替换为对应的数据(容器类型数据,会拆分成每个元素进行赋值) 字符串不可以这样操作!! a = [1,2,3,4,5] a[0:3] = ['a','b','c'] #个数不需要对应 print(a) a[0:3] = ['a','b'] print(a) a[0:3:2] = ['x','y'] #个数需要对应 print(a) >>>['a', 'b', 'c', 4, 5] ['a', 'b', 4, 5] ['x', 'b', 'y', 4, 5]
-
列表的切片删除:del list[开始:结束:步进]
a = [1,2,3,4,5] del a[1:3:2] #注意开始值和结束值是左闭右开的!! print(a) >>>[1, 3, 4, 5]
【注意!!!】开始值和结束值是左闭右开的!!a[0:2]取的值是a[0]和a[1]!
4. 列表相关函数
-
len(list):检测当前列表的长度,列表中元素的个数
-
list.count():检测当前列表中指定元素出现的次数
-
list.append():向列表的尾部追加新的元素,返回值为None
a = [1,2,3,4,5] a.append(678) print(a) print(a.append(90)) #直接输出则为None,但是已经append了 print(a) >>>[1, 2, 3, 4, 5, 678] None [1, 2, 3, 4, 5, 678, 90]
-
list.insert():向列表中指定的索引位置添加新的元素,返回值为None
#如果索引不存在,则添加在列表最后 a = [1,2,3,4,5] a.insert(4,6) a.insert(100,80) print(a) print(a.insert(1,100)) print(a) >>>[1, 2, 3, 4, 6, 5, 80] None [1, 100, 2, 3, 4, 6, 5, 80]
-
list.pop():对指定索引的元素做出栈操作,返回值为出栈的元素,默认为最后一个元素,如果索引不存在则报错
【通过索引删除】
a = [1,2,1,4,5] print(a.pop()) #此时已经出栈 print(a) a.pop(1) print(a) >>>5 [1, 2, 1, 4] [1, 1, 4]
-
list.remove():删除第一个指定值,返回值为None,如果没有则报错
【通过值删除,且只删除第一个】
a = [1,2,1,4,5] print(a.remove(1)) print(a) >>>None [2, 1, 4, 5]
-
list.index(目标,开始,结束):查找指定元素在指定索引范围内内第一次出现的索引位置,如果不存在则报错
a = [1,2,1,4,5] print(a.index(1)) print(a.index(1,2,100)) #结束值超出列表长度也不会报错 >>>0 2
-
list.extend():接收一个容器类型的数据,把容器中的元素追加到原列表中
【注意extend和append insert的区别!】
a = [1,2,3] a.append('abc') print(a) a.insert(0,'z') print(a) a.extend('456') #如果是字典,只添加key print(a) >>>[1, 2, 3, 'abc'] ['z', 1, 2, 3, 'abc'] ['z', 1, 2, 3, 'abc', '4', '5', '6'] #append和insert每次都只能添加一个元素
-
list.clear():清空列表,返回值为None
#接上 print(a.clear()) print(a) >>>None []
-
list.reverse():列表翻转,返回值为None
a = [1,2,3] a.reverse() print(a) >>>[3, 2, 1]
-
list.sort(key,reverse):对列表进行排序,返回值为None
a = [1,-3,2] a.sort() #从小到大 a.sort(reverse=True) #从大到小 a.sort(key=abs) #按照函数处理结果进行排序 a.sort(key=lambda x:x%2,reverse=True)#按照函数处理结果从大到小排
####【和sorted()类似,但是注意区别!】
sorted(iterable,[reverse,key]):里面放容器类型数据,reverse在前,key在后;不管容器类型是啥,返回值为排序后的列表
sort(key,reverse):只能用在列表里的方法,key在前,reverse在后,对列表进行排序,返回值为None
-
list.copy():复制当前的列表
#如果对copy后的列表进行一维列表操作,不会改变原列表 a = [1,-3,2,['a','b','c']] b = a.copy() del b[1] print(a) print(b) >>>[1, -3, 2, ['a', 'b', 'c']] [1, 2, ['a', 'b', 'c']] #如果对copy后的列表进行多维列表操作,则会改变原列表 a = [1,-3,2,['a','b','c']] b = a.copy() del b[3][1] print(a) print(b) >>>[1, -3, 2, ['a', 'c']] [1, -3, 2, ['a', 'c']]
深拷贝与浅拷贝
浅拷贝:list.copy()
浅拷贝只能拷贝列表中的一维元素,如果列表中存在多维元素或容器,则引用而不是拷贝;浅拷贝只能拷贝当前列表,不能拷贝列表中的其他元素(如多维列表)
使用copy函数或者copy模块中的copy函数拷贝的都是浅拷贝
【如果是一个被拷贝的列表,对它的多维列表元素进行操作时,会导致原列表中的多维列表也发生了变化,如上面所演示的代码,原因如下】
a = [1,-3,2,['a','b','c']]
b = a.copy()
print(id(a),id(b))
print(id(a[3]),id(b[3]))
>>>#a和b地址不一样
#但是a[]和b[]的地址是一样的
#所以浅拷贝中修改多维列表,会一起变
####深拷贝:使用copy模块中的 copy.deepcopy(list)
深拷贝就是不光拷贝了当前的列表,同时把列表中的多维元素或容器也拷贝了一份,而不是引用
import copy
a = [1,-3,2,['a','b','c']]
b = copy.deepcopy(a)
del b[3][1]
print(a)
print(b)
>>>[1, -3, 2, ['a', 'b', 'c']]
[1, -3, 2, ['a', 'c']]
#同样通过id()函数,可以看到深拷贝中a和b地址不同
##5. 列表推导式/解析式:一个更简单的创建列表的方法
结果变量 = [变量或变量的处理结果 for 变量 in 容器类型数据]
【好多leetcode题都用推导式来简化】
###5.1 基本的列表推导式
#创建一个平方列表
#第一种:普通方法
varlist = []
for i in range(10):
varlist.append(i**2)
#第二种:map()函数
a = list(map(lambda x:x**2,range(10)))
#第三种:使用列表推导式
a = [i**2 for i in range(10)]
#'1234' ==> [2,4,6,8]
#第一种:普通方法
a = '1234'
b = []
for i in a:
b.append(int(i)*2)
#第二种:列表推导式
a = '1234'
b = [int(i)*2 for i in a]
#第三种:列表推导式+位运算
b = [int(i)<<1 for i in a]
5.2 带有判断条件的列表推导式
结果变量 = [变量或变量的处理结果 for i in 容器类型数据 条件表达式]
#0-9,求所有的偶数
#第一种:普通方法
a = []
for i in range(10):
if i % 2 == 0:
a.append(i)
#第二种:列表推导式
a = [i for i in range(10) if i % 2 == 0]
5.3 对于嵌套循环的列表推导式
#[1,2,3],[3,1,4] ==>把两个列表中的元素两两组合,要求组合的元素不能重复
#第一种:普通方法
a = []
for x in [1,2,3]:
for y in [3,1,4]:
if x != y:
a.append((x,y))
#第二种:列表推导式
a = [(x,y) for x in [1,2,3] for y in [3,1,4] if x != y]
'''
# 下面这个 3x4的矩阵,它由3个长度为4的列表组成,交换其行和列
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
==>
[
[1, 5, 9],
[2, 6, 10],
[3, 7, 11],
[4, 8, 12]
]
'''
#常规方法
arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
a = []
for i in range(4):
x = []
for row in arr:
x.append(row[i])
a.append(x)
print(a)
#列表推导式
a = [[row[i] for row in arr]for i in range(4)]
#练习题
# 1 使用列表推到式完成 把字典中的键值对转换成 key=value 的数据格式
'''
字典 {'user':'admin','age':20,'phone':'133'}
列表 ['user=admin','age=20','phone=133']
'''
#常规方法
a = {'user':'admin','age':20,'phone':'133'}
b = []
for i in a:
b.append(i + '=' + str(a[i]))
print(b)
#列表推导式
b = [i + '=' + str(a[i]) for i in a]
## 2 用列表推到式完成 把列表中的所有字符全部转为小写
# ['AAAAA','bbBb','CCCcc'] ==> ['aaaaa','bbbbb','ccccc']
#常规
a = ['AAAAA','bbBb','CCCcc']
b = []
for i in a:
b.append(i.lower())
#列表推导式
b = [i.lower() for i in a]
##3 x 是0-5之间偶数,y是0-5之间奇数,把x,y组成一个元组,放到列表中
#常规
a = []
for i in range(5):
for j in range(5):
if i%2 == 0 and j%2 == 1:
a.append((i,j))
print(a)
#列表推导式
a = [(x,y) for x in range(6) for y in range(6) if x%2==0 and y%2==1]
【注意!这里一开始犯了个错误:
a = [(x,y) for x,y in range(6) if x%2==0 and y%2==1]
不能这样缩写!】
# 4 使用列表推到式 完成 九九乘法表
#常规:
a = []
for i in range(1,10):
for j in range(1,i+1):
b = f'{i}x{j}={i*j}'
a.append(b)
print(a)
#但是这样不分行
#常规分行
for i in range(1,10):
for j in range(1,i+1):
print(f'{i}x{j}={i*j}',end= ' ')
print()
#推导式,不分行
a = [f'{i}x{j}={i*j}' for i in range(1,10) for j in range(1,i+1)]
# 5 求M,N中矩阵和元素的乘积
'''
M=[
[1,2,3],
[4,5,6],
[7,8,9]
]
N = [
[2,2,2],
[3,3,3],
[4,4,4]
]
实现乘积的结果
(1)==> [2,4,6,12,15,18,28,32,36]
(2)==> [[2,4,6],[12,15,18],[28,32,36]]
'''
#(1)
M=[
[1,2,3],
[4,5,6],
[7,8,9]
]
N = [
[2,2,2],
[3,3,3],
[4,4,4]
]
a = [M[i][j]*N[i][j] for i in range(3) for j in range(3)]
print(a)
>>>[2, 4, 6, 12, 15, 18, 28, 32, 36]
#这里要注意for i和for j的顺序!
a = [M[i][j]*N[i][j] for j in range(3) for i in range(3)]
print(a)
>>>[2, 12, 28, 4, 15, 32, 6, 18, 36]
#(2)
a = [[M[i][j]*N[i][j] for j in range(3)] for i in range(3)]
print(a)
>>>[[2, 12, 28], [4, 15, 32], [6, 18, 36]]