Python的数据容器
Python数据容器类型的基本知识
主要学习,python数据容器的四大类型:列表、元组、字典和集合的基本知识。
列表
列表标志性符号:[]
列表的创建
基本方法两种:
- 使用[]创建列表
- 使用list()创建列表
# 第一种方法
data = [10, 20, 30, 40, 50]
# 第二种方法,使用list(),用于字符串,可迭代型数据
data1 = list("hello")
print(data)
print(data1)
输出结果:
[10, 20, 30, 40, 50]
[‘h’, ‘e’, ‘l’, ‘l’, ‘o’]
- 使用[]创建列表时,列表内数据类型没有限制,可任意
data = [10, 1.1, 'hello', True, 3.1415]
print(data)
输出结果:
[10, 1.1, ‘hello’, True, 3.1415]
空列表
# 可以建立空列表,即列表内没有任何元素。
data = []
data1 = list()
列表的索引与切片
列表的索引与切片操作方法与字符串的索引与切片相同,注意step的正负,即取值时的方向。
data = [10, 20, 30, 40, 50]
data1 = list("hello")
print(data[:-3]) #输出[10, 20]
print(data1[2:5]) #输出['l', 'l', 'o']
详细,请看上一篇学习笔记中有关字符串操作中的索引与切片。
列表的特点
- 列表中的元素时有序的,且可以有重复元素
- 列表可存储元素没有限制,类型无限制,数量无限制
- 列表是一种可变容器类型,是可修改的,可进行增、删、插入、替换、合并等操作
列表的常用操作函数
序号 | 函数 | 功能 |
---|---|---|
1 | append() | 在已有列表中追加元素。 .append(元素) |
2 | insert() | 在已有列表的某个位置插入元素。 .insert(位置,元素) |
3 | sort() | 排序。默认升序排列,降序则输入参数.sort(reverse=True),如果含多种类型数据,比如既有’str’,也有’bool’,还有数值,则报错TypeError: ‘<’ not supported between instances of ‘str’ and ‘bool’ |
4 | remove() | 删除某个元素。如果表中没有被删除元素,则会报错。.remove(元素) |
5 | pop() | 删除某个位置的元素。.pop(位置) |
6 | clear() | 清空列表。.clear() |
7 | del | 删除列表。del 列表 |
代码示例:
# 创建两个列表
data0 = [10, 20, 30, 40, 50]
data1 = [1, 2, 3]
# 合并data0和data1
data = data0 + data1
print('合并列表:', data)
# 追加一个元素60到data0中
data0.append(60)
print('追加元素:', data0)
# 在data0中的第2位置处插入一个元素25
data0.insert(2, 25)
print('插入一个元素:', data0)
# 把data分别升序和降序排列
data.sort()
print("升序排列:",data)
data.sort(reverse=True)
print("降序排列:", data)
# 找到data中的元素1,然后修改为60
S = data.index(1)
data[S] = 60
print('修改后的列表:', data)
# 删除data0中的25
data0.remove(25)
print("删除了一个元素:", data0)
# 删除位置第2位的元素30
data0.pop(2)
print("删除了第2位的数字30:" , data0)
# 清空data0
data0.clear()
print('清空列表后,列表里还有多少元素:',len(data0))
# 删除列表data1
del data1
print(data1)
运行结果:
合并列表: [10, 20, 30, 40, 50, 1, 2, 3]
追加元素: [10, 20, 30, 40, 50, 60]
插入一个元素: [10, 20, 25, 30, 40, 50, 60]
升序排列: [1, 2, 3, 10, 20, 30, 40, 50]
降序排列: [50, 40, 30, 20, 10, 3, 2, 1]
修改后的列表: [50, 40, 30, 20, 10, 3, 2, 60]
删除了一个元素: [10, 20, 30, 40, 50, 60]
删除了第2位的数字30: [10, 20, 40, 50, 60]
清空列表后,列表里还有多少元素: 0
Traceback (most recent call last):
File “c:\Users\lazyb\Documents\python_doamon\dome.py”, line 43, in
print(data1)
NameError: name ‘data1’ is not defined. Did you mean: ‘data0’?
- 尝试过程中,我发现列表的一些操作中,如果我直接把操作后的结果赋值给一个新的变量,那么会返回“None”,不知道原因是什么,暂时记录保留一下:
data = [1, 2, 3, 4]
data1 = data.append(5)
print(data1) #输出None
#必须要执行后再赋值,输出才对
data = [1, 2, 3, 4]
data.append(5)
data1 = data
print(data1)
应该是因为,列表是属于可变容器类型,自身元素是可以被更改的,所以在执行一些命令时候,比如上述指令时,要先对自己执行,而后才能赋值给其他变量;
另外,更python的解释型,逐句执行应该也有关系,一行代码不能同时执行2个操作,只能一个一个的来。
追加一个例子,把t添加到list列表里:
list = list("hello")
t = [1, 2, 3]
list.extend(t)
print(list)
元组
元组的标志符号是:()
创建元组
方法一:使用小括号()
data1 = (10, 20, 30, 40)
data2 = 1, 2, 3, 4 # 可以省略小括号
data3 = (1 ,) # 创建单个元素的元组时,要在元素后加一个逗号,
# 不加逗号,会被当做int数据处理
data4 = () # 创建空元组
方法二:使用函数tuple,将其他数据类型转换成元组
data1 = tuple('hello')
# 可以把列表转为元组
lis = [1, 2, 3, 4]
tup = tuple(lis)
# 反之也可以元组转为列表
tup = (1, 2, 3, 4)
lis = (tup)
元组的索引与切片
同列表操作
data = (1, 2, 3, 4, 5, 6, 7, 8, 9)
print(data[1:3]) #输出 (2,3)
print(data[-3:]) #输出 (7,8,9)
print(len(data)) #输出 9
print(data[4]) #输出 5
元组的特点
- 有序
- 元素允许出现重复元素
- 元组是一种不可变容器类型,一旦被创建它的元素就不可更改
- 可看作是不可改变的列表
元组的常用操作
多重变量赋值
# 同时赋值多个变量
x,y,z = (30,40,50)
print(x, y, z)
# 交换两个变量值
x = 3
y = 4
print(x, y)
x, y = (y, x)
print(x, y)
输出结果:
30 40 50
3 4
4 3
元组的拼接
虽然元组不能修改,但是我们可以把2个元组拼接在一起,建立一个新的元组。
元组的拼接不是把一个元组添加到另一个元组,这点与列表不一样。
stud_1 = '张三', '李四', '王五'
stud_2 = '小明', '小红', '小亮'
stud = stud_1 + stud_2
print(stud)
输出结果:
(‘张三’, ‘李四’, ‘王五’, ‘小明’, ‘小红’, ‘小亮’)
元组的内置方法
学习到这里,你会发现在列表中,也介绍过一个称为内置函数的概念。其实应该指的是同一个意思。
除了使用help()获取帮助外,提供了一种更简洁的获取方式,就是使用dir()。
可以作一个对比:
**使用help()时,我们得到的是比较详尽的help内容: **
print(help(tuple))
| count(self, value, /)
| Return number of occurrences of value.
|
| index(self, value, start=0, stop=9223372036854775807, /)
| Return first index of value.
|
| Raises ValueError if the value is not present.
|
而使用dir(),只能得到函数名称列表,没有具体函数功能帮助说明:
print(dir(tuple))
['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
[‘add’, ‘class’, ‘class_getitem’, ‘contains’, ‘delattr’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘getitem’, ‘getnewargs’, ‘gt’, ‘hash’, ‘init’, ‘init_subclass’, ‘iter’, ‘le’, ‘len’, ‘lt’, ‘mul’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘rmul’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘count’, ‘index’]
如果需要查看某个函数的功能帮助,那还需要你继续使用print(help(tuple.函数名))
,进行查看。
关于"count()"和"index()"的简单使用
可看下面代码示例:
stud_1 = '张三', '李四', '王五'
stud_2 = '小明', '小红', '小亮'
stud = stud_1 + stud_2
print(stud)
# 查看tuple内置方法
print(dir(tuple))
# 查看count(函数帮助说明)
print(help(tuple.count))
print(stud.count('小明')) #统计'小明'在元组中出现的次数
print(help(tuple.index))
print(stud)
print(stud.index('小明')) #返回'小明'在元组中的位置
运行结果:
('张三', '李四', '王五', '小明', '小红', '小亮')
['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
Help on method_descriptor:
count(self, value, /)
Return number of occurrences of value.
None
1
Help on method_descriptor:
index(self, value, start=0, stop=9223372036854775807, /)
Return first index of value.
Raises ValueError if the value is not present.
None
('张三', '李四', '王五', '小明', '小红', '小亮')
3
对比元组与列表的区别
- 列表元素可以更改,是可变序列
- 元组创建后,元素不可更改,是不可变序列
- 元组可以看作是不可变的列表,通常情况下,元组用于保存无需修改的内容
- 一些列表中使用的内置函数,在元组里也有
最后强调:注意,元组内元素是不能被修改的
字典
字典的创建
字典创建的方法与列表和元组大同小异,主要有两种:
标志性符号:{}
方法一:直接使用{}创建
方法二:使用函数dict()创建
需要注意的是,字典里元素比较特别,它是由一对键值对组成:
元素:键key:值value
- 每个元素都包含两个部分:键和值,称为键值对
- 每个键值之间用:分割
- 元素间用,分割
示例:一个字典大概如下:
{key1:value1, key2:value2, key3:value3,……}
让我们来建一个某幼儿园2023级的班级人员信息class_info的字典,里边有班级的学生名字
'''三个班级分别是:大班、中班和小班,大班里有一个小朋友张三,中班三个小朋友
小李、小明、小红,小班两个小朋友彤彤、毛毛
'''
class_info = {'class_top':'张三',
'class_middle':['小李', '小明', '小红'],
'class_bottom':['彤彤', '毛毛']
}
print(type(class_info) ) #看看类型
print(class_info)
运行结果:
<class ‘dict’>
{‘class_top’: ‘张三’, ‘class_middle’: [‘小李’, ‘小明’, ‘小红’], ‘class_bottom’: [‘彤彤’, ‘毛毛’]}
特别说明:通过这个示例,其实我们自己可以发现一些字典的特点
- 字典中的键是不可变数据类型,可以是:字符串、数值(整数、浮点)、元组等
- 字典中的值是可变数据类型,可以用列表(列表是可变的,不能作为字典的键)
- 列表、元组和字典都是Python中的一种数据?不知道这么说有没有毛病
字典,想想我们的中华字典,里边很多的信息,所以,我们能不能在这个示例里把每个小朋友的性别、年龄、身高等信息也放进去呢?当然是可以的
更进一步:
'''三个班级分别是:大班、中班和小班,大班里有一个小朋友张三,中班三个小朋友
小李、小明、小红,小班两个小朋友彤彤、毛毛
再加入每个小朋友的性别、年龄和身高
'''
class_info = {'class_top':{'张三':['男', '6岁', '1.45m']},
'class_middle':{'小李':['女', '5岁', '1.31m'],
'小明':['男', '5.5岁', '1.33m'],
'小红':['女', '6岁', '1.35m']
},
'class_bottom':{'彤彤':['女', '3岁', '1m'],
'毛毛':['男', '3.5岁', '1.1m']
}
}
看看运行结果:
<class ‘dict’>
{‘class_top’: {‘张三’: [‘男’, ‘6岁’, ‘1.45m’]}, ‘class_middle’: {‘小李’: [‘女’, ‘5岁’, ‘1.31m’], ‘小明’: [‘男’, ‘5.5岁’, ‘1.33m’], ‘小红’: [‘女’, ‘6岁’, ‘1.35m’]}, ‘class_bottom’: {‘彤彤’: [‘女’, ‘3岁’, ‘1m’], ‘毛毛’: [‘男’, ‘3.5岁’, ‘1.1m’]}}
如果想要熟悉dict()函数创建元组,可以试试,方法与列表和元组类似,这里略过……
空字典
- 字典名 = {}
- 字典名 = dict()
字典的访问
字典的访问,即字典的使用。一般是利用字典里的键来查看对应值的信息
基本格式:字典[键]
利用前边建好的字典,演示几个查询访问的操作:
# 查看字典class_info里中班class_middle里的小朋友有谁?
who_is_in_class_info = class_info['class_middle']
print(who_is_in_class_info)
# 查看毛毛的性别、年龄和身高
print('毛毛的性别、年龄和身高分别是:', class_info['class_bottom']["毛毛"])
# 毛毛几岁了?
# 在访问字典时,其实类似剥皮一样从外到内一层一层查找关键字(就是字典的键)
'''下边指令中为什么会出现[1]呢?因为这时我们查到的是一个列表,
而毛毛的年龄在列表的第二个元素,下标是1'''
print('毛毛的的年龄:', class_info['class_bottom']["毛毛"][1])
运行结果:
{‘小李’: [‘女’, ‘5岁’, ‘1.31m’], ‘小明’: [‘男’, ‘5.5岁’, ‘1.33m’], ‘小红’: [‘女’, ‘6岁’, ‘1.35m’]}
毛毛的性别、年龄和身高分别是: [‘男’, ‘3.5岁’, ‘1.1m’]
毛毛的的年龄: 3.5岁
- 用字典名[]的方式访问字典时,如果访问的键不存在,则会报错。
其他方式,使用.get(key)方法访问字典
Help on method_descriptor:
get(self, key, default=None, /)
Return the value for key if key is in the dictionary, else default.
get访问时如果访问的键不存在,返回None。
print(class_info.get('class_top'))
print(class_info.get('class')) #字典里没有'class'这个键
print(class_info.get("小红")) #也不能直接得到下一层的键值
# 得这样写,怪怪的,没[]的方式简洁
print(class_info.get("class_middle")['小明'])
print(class_info.get("class_middle").get('小明'))
运行结果:
{‘张三’: [‘男’, ‘6岁’, ‘1.45m’]}
None
[‘男’, ‘5.5岁’, ‘1.33m’]
[‘男’, ‘5.5岁’, ‘1.33m’]
应该还有更好的表述,或者操作方法,初学到此暂停。
另外,还有几个函数介绍:
- items() :返回字典的所有键值对
- keys():返回字典所有的键
- values():返回字典所有的值
print(class_info.items())
print('********************这是一条分割线****************************')
print(class_info.keys())
print('********************这是一条分割线****************************')
print(class_info.values())
运行结果:
dict_items([(‘class_top’, {‘张三’: [‘男’, ‘6岁’, ‘1.45m’]}), (‘class_middle’, {‘小李’: [‘女’, ‘5岁’, ‘1.31m’], ‘小明’: [‘男’, ‘5.5岁’, ‘1.33m’], ‘小红’: [‘女’, ‘6岁’, ‘1.35m’]}), (‘class_bottom’, {‘彤彤’: [‘女’, ‘3岁’, ‘1m’], ‘毛毛’: [‘男’, ‘3.5 岁’, ‘1.1m’]})])
********************这是一条分割线****************************
dict_keys([‘class_top’, ‘class_middle’, ‘class_bottom’])
********************这是一条分割线****************************
dict_values([{‘张三’: [‘男’, ‘6岁’, ‘1.45m’]}, {‘小李’: [‘女’, ‘5岁’, ‘1.31m’], ’ 小明’: [‘男’, ‘5.5岁’, ‘1.33m’], ‘小红’: [‘女’, ‘6岁’, ‘1.35m’]}, {‘彤彤’: [‘女’, ‘3岁’, ‘1m’], ‘毛毛’: [‘男’, ‘3.5岁’, ‘1.1m’]}])
字典的特点
总结了几点:
- 字典的每个元素都是由两项组成:键和值,统称为键值对
- 字典里的元素是无序的,只能通过键来获取对应的值
- 字典中,一般不存在相同的键,最好不要重复。如果出现相同键,则以最后一个键值为主,即最后一个键的值会替代之前相同的键值。
- 列表是可变数据,不能用来做字典的键,但可以做值
字典的常用操作
这里的常用操作其实就是一些增、删、修改等操作,值得注意的是在操作中,我们是需要通过字典的访问方式取到需要操作的位置的。
随着位置变化,数据涉及的类型也会变化,某些时候是dict,某些时候又变为list型
类型变化了,在操作时就要使用对应类型的操作方法,list时用list的操作方法和函数,这点可以注意下边给的示例:
完整操作示例:
'''三个班级分别是:大班、中班和小班,大班里有一个小朋友张三,中班三个小朋友
小李、小明、小红,小班两个小朋友彤彤、毛毛
'''
class_info = {'class_top':{'张三':['男', '6岁', '1.45m']},
'class_middle':{'小李':['女', '5岁', '1.31m'],
'小明':['男', '5.5岁', '1.33m'],
'小红':['女', '6岁', '1.35m']
},
'class_bottom':{'彤彤':['女', '3岁', '1m'],
'毛毛':['男', '3.5岁', '1.1m']
}
}
# print(type(class_info) ) #看看类型
# print(class_info)
print(type(class_info['class_top'])) # 这里输出类型是dict
# 大班新来两个同学了,王五和陈四,暂时不知道王五的年龄和身高
class_info['class_top']['王五'] = ['男', '6岁']
class_info['class_top']['陈斯'] = ['女', '6岁', '1.43m']
print(class_info['class_top'])
# 中班的小李因为家长工作调动,要随爸爸妈妈去其他城市了。
# 我们要把小李在字典里的信息删除掉,使用del
print('幼儿园中班有哪几个小朋友?')
print(class_info['class_middle'].keys())
del class_info['class_middle']['小李']
print('小李走后还有谁在?')
print(class_info['class_middle'].keys())
# 新学期开学了,新加入的王五和李斯也来上学了,小朋友也做了体检
# 知道了王五小朋友的实际身高
# 张三同学还自己测了血型为O
# 这是需要把新的信息加到字典里
class_top1 = class_info['class_top']['张三']
print(type(class_top1)) # 打印类型,知道class_top1实际是个列表
# 在列表里增加一个值,其实也可以看作在字典里增加值
class_top1.append('血型O')
class_top2 = class_info['class_top']['王五']
class_top2.append('1.4m')
print(class_info['class_top'])
运行结果:
<class ‘dict’>
{‘张三’: [‘男’, ‘6岁’, ‘1.45m’], ‘王五’: [‘男’, ‘6岁’], ‘陈斯’: [‘女’, ‘6岁’, ‘1.43m’]}
幼儿园中班有哪几个小朋友?
dict_keys([‘小李’, ‘小明’, ‘小红’])
小李走后还有谁在?
dict_keys([‘小明’, ‘小红’])
<class ‘list’>
{‘张三’: [‘男’, ‘6岁’, ‘1.45m’, ‘血型O’], ‘王五’: [‘男’, ‘6岁’, ‘1.4m’], ‘陈斯’: [‘女’, ‘6岁’, ‘1.43m’]}
我猜,字典应该也可以用dir()和help()获取帮助信息,不信可以试试。
集合
集合的创建
两种方法:
方法一:使用[]创建
方法二:使用函数set()创建
大致与前边几种相似,但需要注意的是建立空集是只能使用set()函数创建
原因是:{}创建以及被字典占用了,如果使用{}创建的是空字典而不是空集
data = {a, a, b, b, c, c}
print(data) #输出{a,b,c}
-
集合里的每个元素都是唯一的,创建时如果有重复元素,则只会保留一个
-
每次print输出时的顺序不一定相同,因为集合里元素是无序的。
集合的特点
大概就是三个要素:确定性、唯一性、无限性
集合中的元素是无序的,不能使用下标来查询元素
集合中的每一个元素都是唯一的
当使用{}创建集合时,元素的类型只能是不可变的
字典与列表都是可变的数据类型,所以不能写在{}中
元组为不可变类型,可以写在{}中
常用操作
利用集合元素的唯一性,进行列表的去重
说白了就是一个从list—>set—>list的过程
# 创建一个列表
lst = ['a', 'a', 'b', 'b', 'c', 'c']
# 查看原列表情况
print(lst)
# 利用set()把列表转化为集合
lst = set(lst)
print(lst)
# 在转回列表
lst = list(lst)
print(lst)
运行结果:(注意对比输出的变化)
[‘a’, ‘a’, ‘b’, ‘b’, ‘c’, ‘c’]
{‘c’, ‘a’, ‘b’}
[‘c’, ‘a’, ‘b’]
集合中增加和删除元素
增加元素
主要使用add()和update()
- add():增加1个元素
- update():增加多个元素
示例:
# 创建一个列表
lst = ['a', 'a', 'b', 'b', 'c', 'c']
# 查看原列表情况
print(lst)
# 利用set()把列表转化为集合
lst = set(lst)
print(lst)
# 增加d、e两个元素
lst.update('d','e')
print(lst)
# 增加f一个元素
lst.add('f')
print(lst)
运行结果:
[‘a’, ‘a’, ‘b’, ‘b’, ‘c’, ‘c’]
{‘b’, ‘c’, ‘a’}
{‘e’, ‘b’, ‘a’, ‘d’, ‘c’}
{‘e’, ‘b’, ‘a’, ‘d’, ‘f’, ‘c’}
删除操作
主要使用remove()、discard()、clear()和del
- remove():删除集合中元素,不存在时报错,只能删除一个元素
- discard():删除集合中元素,不存在时不报错
- clear():清空集合元素
- del:删除集合
示例:
# 创建一个集合
lst = {'a', 'b', 'c', 'd', 'e', 'f'}
print(lst)
# remove():删除集合中元素,不存在时报错
lst.remove('a')
print(lst)
# lst.remove('a') #到这里会报错
# discard():删除集合中元素,不存在时不报错
lst.discard('a') #a已经在上一步中被删除了
print(lst)
# clear():清空集合元素
lst.clear()
# del:删除集合
del lst
print(lst) #报错,没有lst
运行结果:
{‘f’, ‘d’, ‘b’, ‘c’, ‘a’, ‘e’}
{‘f’, ‘d’, ‘b’, ‘c’, ‘e’}
{‘f’, ‘d’, ‘b’, ‘c’, ‘e’}
set()
Traceback (most recent call last):
File “d:\python_doamon\dome.py”, line 24, in
print(lst) #报错,没有lst
NameError: name ‘lst’ is not defined. Did you mean: ‘list’?
综述
序号 | 名称 | 定义 | 特点 | 用法 |
---|---|---|---|---|
1 | 列表 | 由元素组成的可变序列容器 | 灵活性强,可增、删、改、查,注意深拷贝和浅拷贝问题,任意数据都能作为元素 标志符号[] | list() 追加:append(),删除:remove(),del,通过索引修改数据,可以用下标查询,for循环遍历 |
2 | 元组 | 由元素组成的不可变序列容器 | 建立后就不能修改 标志符号:() | tuple() 可以使用索引和for循环进行查询元素 |
3 | 字典 | 由键值对组成的可变无序容器 | 元素由成对的键值对组成,无序, 键必须唯一且不可变(字符、数字、元组) 操作时有时会使用列表的方法 标志符号:{} | dict() 使用键查询数据:key = values 增、改键名字时直接使用: 字典名[键] = 数据 删除键:del 字典名[键] |
4 | 集合 | 由元素组成的不可变无序容器 | 概念简单,无序,每个元素都是唯一的。 其中的元素实际与字典里的键key相同 标志符号:{} 只能用set()创建空集 | set() 增:集合名.add(元素) 删:集合名.discard(元素) 查:for遍历 |