Python 基本数据类型(四): 列表类型

版权声明:转载请注明来源及作者,谢谢! 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不一样

猜你喜欢

转载自blog.csdn.net/qq_42442369/article/details/84348334