一、前言
本节主要介绍几种数据结构(str、list、tuple、dict、set)及其应用(增删改查和注意事项)。
环境说明:Python 3或anaconda 3,使用编辑器 jupyter notebook(anaconda自带,Python自行安装),通过命令行或其他编辑器也可以。
二、Python的数据结构
2.1 序列类型结构:str、tuple、list
相同点:
- 三者都有正负索引(有序序列),可以通过索引取值,支持循环遍历每个元素
- 都支持切片
- 都支持判断某元素是否在序列内(in/not in)
不同点:
- str和tuple创建之后就不可修改,只支持查询,而list支持增删改查
- str只能使用字符串,tuple和list支持任意数据类型
- 内存存储,值相同的str 分别赋值给两个变量,两个变量的id一致,即值相同的str 分配到的存储空间是同一个,如果同一个变量前后赋值两次,两次的id不同,而tuple和list的上述两种情况的id都不同。判断空间是否一致可以使用
val1 is val2
,查看空间id使用id(val)
,判断值是否相等则使用val1 == val2
# 字符串
a = '1'
b = '1'
print(a == b) # 结果为:True
print(a is b) # 结果为:True
print(id(b)) # 结果为:23331617072
b = '2'
print(id(b)) # 结果为:23331774640
# tuple
a = 1,2
b = 1,2
print(a == b) # 结果为:True
print(a is b) # 结果为:False
print(id(b)) # 结果为:23361861568
b = 1,2,3
print(id(b)) # 结果为:23361862208
# list
a = [1,2]
b = [1,2]
print(a == b) # 结果为:True
print(a is b) # 结果为:False
print(id(b)) # 结果为:23362359168
b = [1,2,3]
print(id(b)) # 结果为:23362319488
2.1.1 查
两种取法:一个是取单个值,一个是取切片。
不同点:
- 语法不同
- 取单值的格式:【列表名[索引值]】;
- 取切片的格式:【列表名[左索引值 : 右索引值]】(中间用冒号进行隔开),取得的切片的数据类型还是列表。
- 返回的对象可能不同
- 取单值:字符串返回的还是字符串,元组和列表取值返回的是对应的元素,元素是什么数据类型返回的值也是对应的数据类型;
- 取切片:原变量是什么数据类型,返回的就是什么数据类型,即字符串切片返回的还是字符串,元组切片返回的还是元组,列表切片返回的还是列表。
# 针对以下前三行代码,分别保留一行不注释,查看运行结果,取数逻辑一致,返回形式根据原变量的类型会有些不同(不同点参考代码前文字说明)
val = '56789'
# val = (5,6,7,8,9)
# val = [5,6,7,8,9]
# 取值,没有冒号
print(val[2]) # 取出第2位
print(type(val[2])) # str结果为<class 'str'>,tuple和list结果为:<class 'int'>
# 取切片,带冒号
# 左边空,取到第0位,从第0位开始,取n个元素。
print(val[0:2]) # 取出第0、1位
print(val[:2]) # 取出第0、1位
print(type(val[:2]))# tuple结果为:<class 'tuple'>,list结果为:<class 'list'>
# 右边空,表示从第m个元素开始取到尽头,即最后一位;
print(val[2:]) # 取出第2位到结束
# 冒号两边空,表示从第0位到最后一位,取整一个列表,相当于复制。
print(val[:])
print(val[0:5])
# 冒号左右都有数字([m,n])时,表示从第m个元素开始取,取到第(n-1)个。共取出(n-m)个元素。
print(val[1:3]) # 取出第1、2位
print(val[2:4]) # 取出第2、3位
切片小结:取法口诀:左取右不取,空则取到头。(假设n>m>0)
(1)[ :n],冒号左边空(或者为0),,表示从头,即第0位开始,取到第(n-1)个元素,共取n个元素;
(2)[m:],右边空,,表示从第m个元素开始取到尽头,即最后一位;
(3)[ : ],冒号两边空,,表示从第0位到最后一位,取整一个列表,相当于复制。
(4)[m : n],冒号左右都有数字时,,表示从第m个元素开始取,取到第(n-1)个。共取出(n-m)个元素。
取切片的时候,还有第3个参数,这个参数可以指定步数,即每几个取一次。默认步数是1,即每个元素都取。具体看看例子:
# 这里拿list示例,其他大同小异
val = [5,6,7,8,9]
print(val[0:5:1]) # 默认情况下,取出第0~4个元素,结果为:[5, 6, 7, 8, 9]
print(val[0:5:2]) # 步数改为2,每两个取一次,取第0、2、4元素,结果为[5, 7, 9]
2.1.2 增
增加元素只有列表支持。
使用的语法:**列表名.append() **或 列表名.extend()。
二者区别:append() 增加一个元素,extend() 可增加多个元素。
ls = [5,6,7]
ls.append(8)
print(ls) # 结果为:[5,6,7,8]
ls.extend([9,0])
print(ls) # 结果为:[5,6,7,8,9,0]
append() 和 extend() 都是在列表末尾增加元素,如果是指定位置增加,可以使用该语法:列表名.insert(索引值, 新元素)。
ls = [5,6,7]
ls.insert(1,4) # 第1位插入4,后面元素索引加1
print(ls) # 结果为:[5, 4, 6, 7]
ls.insert(2,3) # 第2位插入3,后面元素索引加1
print(ls) # 结果为:[5, 4, 3, 6, 7]
insert() 一次也只能插入一个元素,如果要一次性插入多个,可以通过循环或切片实现:
ls = [5,6,7]
insert_params = [3,4] # 需要插入元素列表
begin_index = 1 # 开始位置
# 方法:1:通过循环遍历
for i in insert_params: # 遍历插入元素列表
ls.insert(begin_index,i) # 将值插入到指定的索引中
print(ls) # 结果为:[5, 4, 3, 6, 7]
# 方法2:通过列表拼接
ls = ls[:begin_index] + insert_params + ls[begin_index:]
print(ls) # 结果为:[5, 4, 3, 6, 7]
2.1.3 删
语法1:del 列表名[索引值] ,注意这里del后面是一个空格;
语法2:列表名.remove([元素]),移除指定元素,如果元素重复出现多次,仅移除首次;
语法3:列表名.pop([索引值]),删除对应索引值的元素并返回,即又删又取。
ls = [5,6,7,6,5]
ls.remove(6) # 移除元素6
print(ls) # 结果为:[5, 7, 6, 5]
del ls[2] # 删除索引2对应元素
print(ls) # 结果为:[5, 7, 5]
ls.pop(-2) # 删除倒数第二个元素,并返回该元素,即7
print(ls) # 结果为:[5, 5]
2.1.4 改
修改元素只有列表具备这样的功能。修改元素包含替换值、排序等。
- 修改语法:列表名[旧值的索引值]=新值
- 排序
- 语法1:列表名.sort(key,reverse),修改原列表,reverse是布尔值,False表示升序(默认),True表示降序。key支持自定义排序。
- 语法2:sorted(列表名,key,reverse),返回新的列表。
ls = [5,6,7]
ls[1] = 8
print(ls) # 结果为:[5, 8, 7]
ls.sort()
print(ls) # 结果为:[5, 7, 8]
ls.sort(reverse=True)
print(ls) # 结果为:[8, 7, 5]
ls_new = sorted(ls)
ls_new # 结果为:[5, 7, 8]
print(ls) # 结果为:[8, 7, 5]
# 自定义排序,7->5->8,其他递增
ls = [8,7,1,5,7,0,3]
ls_new = []
num_ls = [7,5,8] # 将指定排序,按顺序放到列表中
for j in num_ls: # 遍历指定排序的元素
for i in range(ls.count(j)): # 取每个元素重复次数进行循环
ls_new.append(j) # 将指定排序的元素添加到新列表
ls.remove(j) # 在原列表移除元素
ls_new = ls_new+sorted(ls) # 将新列表和剩下排好序的列表拼接
print(ls_new)
2.2 映射类型结构:dict
特点:
- 无序:集合内的元素没有顺序
- 支持增删改查操作
- 键值对:通过冒号关联键值对
- 用{}声明
scores = {'小A': 95, '小B': 90}
# 查询
print(scores['小A']) # 结果为:95
# 删除
del scores['小B']
print(scores) # 结果为:{'小A': 95}
# 新增
scores['小D'] = 100
print(scores) # 结果为:{'小A': 95, '小D': 100}
# 修改
scores['小D'] = 99
print(scores) # 结果为:{'小A': 95, '小D': 99}
d = {'小A': 95, '小C': 90}
scores.update(d)
print(scores) # 结果为:{'小A': 95, '小D': 99, '小C': 90}
2.3 集合类型结构:set
特点:
- 无序:集合内的元素没有顺序
- 唯一:集合内的元素没有重复
- 用 {} 声明:集合内的元素通过
{}
括起来。注意在创建空集合,不能直接使用val = {}
,默认是字典。应使用val = set()
- 可以对集合元素进行增删改
st = {1,2,3,3}
print(st) # 结果为:{1, 2, 3}
# 增加元素
st.add(5)
print(st) # 结果为:{1, 2, 3, 5}
# 更新元素
st.update([3,4,5])
print(st) # 结果为:{1, 2, 3, 4, 5}
# 删除元素
st.remove(2) # 删除元素,不存在会报错
print(st) # 结果为:{1, 3, 4, 5}
st.discard(2) # 删除元素,不存在不会报错,删除效果同remove()
print(st) # 结果为:{1, 3, 4, 5}
st_1 = {1,3,6}
st_2 = {2,4,6}
# 交集
print(st_1 & st_2) # 结果为:{6}
# 并集
print(st_1 | st_2) # 结果为:{1, 2, 3, 4, 6}
三、小结
字符串 | 列表 | 元组 | 字典 | 集合 | |
---|---|---|---|---|---|
基本格式 | 引号(单、双、三引号均可),如’A123’ | 中括号[]、逗号分隔。 如[‘小明’,17,5.2] | 小括号()、逗号分隔。如(‘小明’,17,5.2) | 大括号{}、冒号连接键和值、逗号分隔。 如{‘小明’:95,‘小红’:90,‘小刚’:90} | 大括号{}、逗号分隔。 如{17, 5.2, ‘小明’} |
取值 | 字符串名[索引值] 、字符串名[索引值1:索引值2] 正向从0开始计算,反向从-1开始 | 列表名[索引值] 、列表名[索引值1:索引值2] 正向从0开始计算,反向从-1开始 | 元组名[索引值] 、元组名[索引值1:索引值2] 正向从0开始计算,反向从-1开始 | 字典名[键] | \ |
增加元素 | \ | 列表名.append(元素) 、列表名.extend(元素) | \ | 字典名[键] = 值 | 集合名.add(元素) |
修改元素 | \ | 列表名[旧值的索引值]=新值 、列表名.sort() 、列表名.insert(索引值,元素) 、sorted(列表名,key,reverse) | \ | 字典名[键] = 新值 (同新增元素)、字典名.update(新字典) | 集合名.update(集合/序列) |
删除元素 | \ | del 列表名[元素的索引] (空格隔开)、列表名.remove(元素) 、列表名.pop(索引值) | \ | del 字典名[键] (空格隔开) | 集合名.remove(元素) 、集合名.discard(元素) |
注意:所有的符号都是英文符号!
下节预告:条件与循环