版权声明:转载请注明来源及作者,谢谢! https://blog.csdn.net/qq_42442369/article/details/84348334
content
- 列表的创建
- 列表的操作
- 列表的相关方法
- 列表的遍历
- 列表的推导式
- 专栏:解析浅拷贝,深拷贝
1. 列表的创建
# 语法:列表名=[元素1,元素2....]
# 列表的内存结构:内存图
# 计算机内存中列表是有列表对象的。不同的列表对象是不同的。
names=["tom","jerry","kate",1,2,[4,5]]
print(names,type(names))
# ['tom', 'jerry', 'kate', 1, 2, [4, 5]] <class 'list'>
names2=["tom","jerry","kate",1,2,[4,5]]
print(id(names),id(names2))
# 1530963606344 1530963621000 可变数据类型即是值一样,id也不一样
print(id(names[0]),id(names2[0]))
# 1530709131704 1530709131704 但他们第一个元素的id是一样,因为是不可变数据类型
print(id(names[3]),id(names2[3]))
# 1814457376 1814457376 同上
print(id(names[5]),id(names2[5]))
# 1530963493832 1530963621192 id不一样,因为是可变数据类型
print(id(names[5][0]),id(names2[5][0]))
# 1814457472 1814457472 id一样,因为是不可变数据类型
# 定义空列表
nulllist=[]
print(nulllist,type(nulllist))
# [] <class 'list'>
print(len(nulllist))
# 0
# 列表类型的布尔转换
# 至少有一个元素 True,没有元素 Fasle
names=["tom","jerry","kate",1,2,[4,5]]
nulllist=[]
print(bool(nulllist))
print(bool(names))
# False
# True
2. 列表的操作
(1)运算符
# + * in not in is is not == < > =
# 注意: + * ,合并原列表中的元素,形成新列表。
# + 是合并, 将两个列表的元素合在一起,形成新的列表。新创建列表对象进行合并
a=[1,2]
b=[3,4]
print(a+b,a,b)
# [1,2,3,4]
#注意不是这样 [[1,2],[3,4]]
# * 是重复 将列表中的元素进行重复,形成新的列表
a=[1,2]
b=[3,4]
print(a*3)
# [1, 2, 1, 2, 1, 2]
# 注意:不是这样[[1,2],[1,2],[1,2]]
print(a*2+b*3)
# [1, 2, 1, 2, 3, 4, 3, 4, 3, 4]
# in 和 not in: 元素是否在列表对象当中
a=[1,2,3,4,"a"]
print(1 in a)
# True
x="abc"
print("a" in x)
# True
# 注意:列表中的元素可以是多种类型,字符串中的元素就是单个字符串
# is 和 is not 判断对象是否是同一个
# a=[1,2,3]
# b=[1,2,3]
# c=a
# print(a is b) # 注意画内存图 # False
# print(a is c) # True # 再把c绑定到a上
# < > 将列表中的元素逐个比较(根据ascii码比较)
# print([1,2,3]<[4])
# True
(2)索引
# 获得列表中的单个元素
# 语法: 列表名[index]
# index 正数,负数 0 左到右,第一个0 从右到左第一个是-1
# index如果越界会错
# 界限-len(li) len(li)-1
# names=["tom","jerry","kate",1,2,[4,5]]
# print(names[0])
# print(names[5])
# print(names[6])
# x=names[5]
# print(x[0])
# print(names[5][0]) # 二维列表
# #二维列表的元素判断
# names=["tom","jerry","kate",1,2,[4,5]]
# print(4 in names)
# False
# print(4 in names[5])
# True
# 列表是可变的数据类型
# 元素可以被修改 ## 单单指列表这个对象
# x="abc"
# x[0]="l"
# 可变的数据类型:可以被修改
# 在同一个id下,内容可以被修改。
names=["tom","jerry","kate",1,2,[4,5]]
print(id(names)) # 2185102998344
names[0]="tom1"
print(names) # 修改了
print(id(names)) ## id也修改了,2185102998344
(3)切片
# 获取一定区域内的多个元素
# 语法:列表名[start:end:step]
# start 默认0
# end 默认值len(list)
# step 默认1
# 注意方向,负数,从右到左,正数,从左到右
a=["aaa","bb","cc","dd","ee","ff"]
print(a[0:2])
# ['aaa', 'bb'] 注意:切边前开后闭!!!
print(a[-1:-3:-1])
# ['ff', 'ee']
# # 整切片:
# 列表的整切片跟原来对象内容相等,但是不是同一个id,不是同一个对象,所以列表的整切片是新创建的对象
# a=["aaa","bb","cc","dd","ee","ff"]
# b=a[:]
# print(id(a),id(b))
# 1798109147464 1798109147400 id不一样
# print(a[::-1])
# 逆序输出
# 切片的修改和删除
# 通过列表的切片可以修改列表中一定区域元素
# 通过切片修改列表一定要赋予列表
# a = ["aaa","bb","cc","dd","ee","ff"]
# print(a[1:4])
# 切出来的部分
# a[1:4]=[1,2,3,4,5] ## 把切出来的部分修改成你要的内容
# a[1:4]=[] ## 把切出来的部分删除掉
# print(a)
# 如果使用列表的切片进行赋值时,如果给予的是可迭代对象,会将可迭代对象先变成列表,然后再赋给切片
# 如果给予的不是可迭代对象,会报错
a = ["aaa","bb","cc","dd","ee","ff"]
a[1:4]="123"
# ['aaa', '1', '2', '3', 'ee', 'ff']
# 如果给予的是可迭代对象 也能达到效果,但是最好是赋值 输出结果都是:a=["aaa","123","ee","ff"]
print(a)
a[1:4]=["1","2","3"]
print(a)
# ['aaa', '1', '2', '3', 'ee', 'ff'] 这俩都一样
综合练习:
# 向列表中插入一个元素、删除一个元素。
a=["aaa","bb","cc","dd","ee","ff"]
a[1:1]=["new"] # 插入
print(a)
# ['aaa', 'new', 'bb', 'cc', 'dd', 'ee', 'ff']
a[1:2]=[] # 删除
print(a)
# ['aaa', 'bb', 'cc', 'dd', 'ee', 'ff'] 继承上面的结果,把新的new删掉了,否则,就是['aaa', 'cc', 'dd', 'ee', 'ff']
# 交换列表中两个元素
a=["aaa","bb","cc","dd","ee","ff"]
a[1],a[2]=a[2],a[1]
print(a)
# ['aaa', 'cc', 'bb', 'dd', 'ee', 'ff']
3. 列表的相关方法
(1)添加
# 逻辑是:追加 任意 extend append insert extend
# append
向列表的尾部追加【一个】元素,是原地操作(在原有列表上做操作)
# a=["A","B","C","D","E","F"]
# print(a.append("GG"))
# 单纯的对象加append方法输出结果是 None
# print(a)
# 结果最后追加内容: ['A', 'B', 'C', 'D', 'E', 'F', 'GG']
# replace
# s="abc"
# print(s.replace("a","7"))
# print(s)
# 输出结果是abc,所以列表里的跟字符串里的replace方法不一样,replace方法未改动原字符串;基本上字符串里的都是生成新的字符串
# insert
# 向列表中插入指定的 【一个】元素 ## 根据指定位置插入
# a.insert(index,object)
# index: 要插入的位置
# object: 要插入的内容
# a=["A","B","C","D","E","F"]
# a.insert(2,"new")
# print(a)
# 能不能使用insert达到append?可以
# a.insert(len(a),"p")
# print(a)
# + 合并,新创建列表进行合并或者添加元素
# extend 合并,一次追加多个元素,原地修改,在原有列表上追加
# a=["A","B","C","D","E","F"]
# a.extend([1,2,3]) ## ['A', 'B', 'C', 'D', 'E', 'F', 1, 2, 3]
# print(a)
(2)删除
# pop remove del clear
# pop:删除指定位置的元素,一次只能删一个,原地删除
(记忆python中的pop并不是别的单词的缩写,因为pop本身就有“伸出”的意思
# pop的返回值是被删除掉的元素
# pop中index为空,默认列表中最后一个元素
# pop索引不存在会报错
# a=["A","B","C","D","E","F"]
# a.pop()
# print(a)
# 删除掉最后一个F
# ['A', 'B', 'C', 'D', 'E']
# a.pop(2)
# print(a)
# ['A', 'B', 'D', 'E', 'F']
# 删除掉了第二个元素C,是原地操作
# print(a.pop(2))
# C 注意:单独输出.pop方法,是将选中的元素输出
# index是要删除元素的位置
# del 删除列表中的元素
(根据索引删除,跟pop类似,只不过应用的是关键字而已)
a=["A","B","C","D","E","F"]
del a[0]
print(a)
# ['B', 'C', 'D', 'E', 'F']
a=["A","B","C","D","E","F"]
del a
print(a)
# name 'a' is not defined
# remove 删除指定内容的元素,一次只能删一个,原地删除
# a=["A","B","C","D","E","F"]
# a.remove("D")
# print(a)
# clear 清空列表中的元素
# a=["A","B","C","D","E","F"]
# a.clear() ## 只是清空a,不是删除a,删除a需要用del
# print(a)
# []
(3)检索、统计
a=["A","B","C","D","E","F","A","A"]
# index返回元素所在的位置,可以指定start和end
print(a.index("E"))
print(a.index("gg")) # 如果找不到会报错,脾气不好
# 'gg' is not in list
# count: 统计某个元素的个数
# print(a.count("A"))
(4)反向,排序
#反向
# a=["A","B","C","D","E","F","A","A"]
# a.reverse() # 原地反向, 原列表就已经被反向,跳一步,输出原数列
# print(a)
# ['A', 'A', 'F', 'E', 'D', 'C', 'B', 'A']
# a=["A","B","C","D","E","F","A","A"]
# print(list(reversed(a))) # reversed内置方法不是原地反向,直接输出
# print(a)
# ['A', 'B', 'C', 'D', 'E', 'F', 'A', 'A'] a没有改变,不是原地反向,是内置方法
# 排序
a=["A","B","C","D","E","F","A","A"]
a.sort()
a.sort(reverse=True)
# 默认reverse参数=False升序 , 原地排序
print(a)
# ['A', 'A', 'A', 'B', 'C', 'D', 'E', 'F']
# a=["A","B","C","D","E","F","A","A"]
# print(sorted(a)) ##和reversed(a)一样,不是原地排序,新建列表进行排序 ,返回值是原列表,是内置方法
# ['A', 'A', 'A', 'B', 'C', 'D', 'E', 'F']
# print(a)
# ['A', 'B', 'C', 'D', 'E', 'F', 'A', 'A']
# b="addfadjlkg"
# print(sorted(b)) ## 返回值是原列表
# print("".join(sorted(b))) ## 用join方法 将sorted后返回的列表 拼接成字符串
# 形成光滑的字符串,没有中括号,没有引号 : aadddfgjkl
(5)列表的复制
① 赋值
# 内存图
# a=[1,2,[3,4]]
# b=a
# print(b)
# print(id(a),id(b))
# a和b是同一个对象 地址 2710116604296 2710116604296
# a[0]="new"
# a[2][0]="new"
# print(a,b)
# print(a is b)
# True 本身就是赋值方法 即使更改某个元素也一样
在这里插入代码片
② 浅拷贝
# 在列表下copy方法
# copy包下copy
# 整切片
# 只拷贝当前列表对象(第一层),其他层无论是可变类型还是不可变类型都不复制
# 如果元素是不可变数据类型,原对象的修改不影响拷贝对象,
# 如果元素是可变数据类型,元对象的修改影响拷贝对象。
# 内存图
# 浅拷贝特点: # 只拷贝当前列表对象(第一层),其他层无论是可变类型还是不可变类型都不复制
# 在列表下copy方法copy方法
a=[1,2,[3,4]]
b=a.copy()
print(id(a),id(b))
print(id(a[0]),id(b[0]))
print(id(a[2]),id(b[2]))
# 1916631432008 1916631446856
# 1814457376 1814457376
# 1916631319496 1916631319496
a=[1,2,[3,4]]
# c=[1,2,[3,4]]
b=a.copy()
print(id(a),id(b))
# 不一样 1684392688456 1684392703304
a[0]="new"
a[2][0]="new"
print(a,b)
# a: ['new', 2, ['new', 4]] b: [1, 2, ['new', 4]]
# 注意: 对于可变类型的元素(列表),你变了我就跟着变,不可变数据类型就没有变
print(id(a[0]),id(b[0]))
# 2216897637880 1814457376 不一样
print(id(a[2]),id(b[2]))
# 2060635131720 2060635131720
# 所以结论是: # 如果元素是不可变数据类型,原对象的修改不影响拷贝对象,
# 如果元素是可变数据类型,元对象的修改影响拷贝对象。
# copy包下copy
import copy
a=[1,2,[3,4]]
d=copy.copy(a)
print(id(a),id(d))
# 不一样 1684392688456 1684392703304
print(id(a[0]),id(d[0]))
# 一样 1814457376 1814457376
print(id(a[2][0]),id(d[2][0]))
# 一样 1814457440 1814457440
# 整切片
a=[1,2,[3,4]]
b=a[:]
print(id(a),id(b))
# 2296421824264 2296421783944 地址不一样
③ 深拷贝
# copy包下deepcopy方法
# 一直拷贝到不可变元素为止,不止拷贝一层
# import copy
# a=[1,2,[3,4]]
# b=copy.deepcopy(a)
# # c=[1,2,[3,4]]
# print(id(a),id(b))
#不一样: 2016033397512 2016033460296
# print(id(a[0]),id(b[0]))
# 1672965152 1672965152 不可变数据类型,不变
# print(id(a[2]),id(b[2]))
# 2016033397320 2016033398728 可变数据类型,变化
# print(id(a[2][0]),id(b[2][0]))
# 1672965216 1672965216 一样
# import copy
# a=[1,2,[3,4]]
# b=copy.deepcopy(a)
# a[0]="new"
# a[2][0]="new"
# print(a,b)
# 有内存图,只有不可变类型不变,可变数据类型都是新的
4. 列表的遍历
# 第一种
# li=[1,2,3,4,5]
# for i in li:
# print(i)
# 第二种 根据索引遍历
# li=[1,2,3,4,5]
# for i in range(5): ## 一共5个元素,
# print(li[i]) ## 我要获得每个元素,就是li的[i]个元素,这个更好用
# 有时候涉及到交换位置,必须还会根据索引遍历
# 这两种方法都可以
# 第三种 enumerate
# li=[1,2,3,4,5]
# for index,i in enumerate(li):
# print(index,i) ## 索引 元素 ## 这三种方法都可以
# 遍历多维列表:嵌套for循环
li=[[1,2],[3,4]]
# for i in li:
# for j in i:
# print(j)
# 用range怎么用?
li=[[1,2],[3,4]]
for i in range(2):
# 2个元素 当前i是索引,不是元素,所以得遍历索引;不能in i,得in li的[i]个元素
for j in range(len(li[i])): # li[i]是当前元素,要先获得它的len,再获得索引
print(li[i][j]) # 这是是li第i个元素的第j个元素
"""
1
2
3
4
"""
li=[[1,2],[3,4]]
for i in range(len(li)):
for j in range(len(li[i])):
print(li[i][j])
"""
1
2
3
4
"""
li = ['a','b','c']
for caocao in li: ## 循环条件
print('给定的字母是 %s' %caocao)
print(li) ## 所以li其实是给定的次数
print(caocao)
"""
给定的字母是 a
['a', 'b', 'c']
a
给定的字母是 b
['a', 'b', 'c']
b
给定的字母是 c
['a', 'b', 'c']
c
"""
li = list(range(5))
print(li,type(li))
# [0, 1, 2, 3, 4] <class 'list'>
for i in list(range(5)):
print(i)
print(list(range(5)))
"""
0
[0, 1, 2, 3, 4]
1
[0, 1, 2, 3, 4]
2
[0, 1, 2, 3, 4]
3
[0, 1, 2, 3, 4]
4
[0, 1, 2, 3, 4]
"""
5. 列表的推导式
# 简化的构建新列表
# 当已经具有一个迭代对象,希望新构建列表
# 格式:[表达式 for i in 迭代对象 if 条件]
# 表达式就是形成新列表的元素
# 简化的构建新列表
# 当已经具有一个迭代对象,希望新构建列表
# 格式:[表达式 for i in 迭代对象 if 条件]
# 表达式就是形成新列表的元素
专栏:解析浅拷贝,深拷贝
Question:
阐述一下python中列表的深拷贝与浅拷贝
浅拷贝:列表下的copy方法,copy包下的copy方法,列表的切片
只复制当前列表对象的第一层。
深拷贝:copy包下的deepcopy
一直复制到不可变类型对象为止。
# 代码尝试:
# a = [1,[2,3],4]
# b = a.copy()
# print(id(a),id(b)) # id不一样,复制成功;第一层
# print(id(a[0]),id(b[0])) #id一样,没有复制;第二层
# print(id(a[1]),id(b[1])) #id一样,第二层
# print(id(a[1][0]),id(b[1][0])) #id一样,没有复制;第三层
# a[0] = 'y'
# print(id(a[0]),id(b[0])) # id不一样 b不受影响
# print(id(a[1]),id(b[1])) #id一样
# print(id(a[1][0]),id(b[1][0])) #id一样 b受影响
# a[1] = 'y'
# print(id(a[0]),id(b[0])) # id一样 b受影响
# print(id(a[1]),id(b[1])) #id不一样
# print(id(a[1][0]),id(b[1][0])) #id更不一样 b不受影响
# a[1][0] = 'y'
# print(id(a[0]),id(b[0])) # id一样 b受影响
# print(id(a[1]),id(b[1])) #id一样
# print(id(a[1][0]),id(b[1][0])) #id一样 b受影响
# import copy
# a = [1,[2,3],4]
# b = copy.deepcopy(a)
# print(id(a),id(b)) # id不一样,复制成功,第一层
# print(id(a[0]),id(b[0])) #id一样
# print(id(a[1]),id(b[1])) #id不一样
# print(id(a[1][0]),id(b[1][0])) #id一样
# a[0] = 'y'
# print(id(a[0]),id(b[0])) # id不一样 b不受影响
# print(id(a[1]),id(b[1])) #id不一样
# print(id(a[1][0]),id(b[1][0])) #id一样 b受影响
# a[1] = 'y'
# print(id(a[0]),id(b[0])) # id一样 b受影响
# print(id(a[1]),id(b[1])) #id不一样
# print(id(a[1][0]),id(b[1][0])) #id不一样 b不受影响
# a[1][0] = 'y'
# print(id(a[0]),id(b[0])) # id一样
# print(id(a[1]),id(b[1])) #id不一样
# print(id(a[1][0]),id(b[1][0])) #id不一样