Python 5 数据容器
数据容器入门
Python中的数据容器:一种可以容纳多份数据的数据类型,容纳的每一份数据称之为1个元素
每一个元素,可以是任意类型的数据,如字符串、数字、布尔等
数据容器根据特点的不同,如:
- 是否支持重复元素
- 是否可以修改
- 是否有序,等
分为5类,分别是:
列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)
列表的定义语法
列表内的每一个数据,称之为元素
- 以[]作为标识
- 列表内每一行之间用,用逗号隔开
列表可以一次存储多个数据,且可以为不同的数据类型,支持嵌套
Demo
1 | """ |
运行结果
1 | ['hello', 'world', 'python'] |
列表的下标索引
列表中的每一个元素,都有其位置下标索引,从前向后的方向,从0开始,依次递增
我们只需要按照下标索引,即可取得对应位置的元素
或者,可以反向索引,也就是从后向前,从-1开始,依次递减(-1、-2、-3…..)
如果列表是嵌套的列表,同样支持下标索引
Demo
1 | # 通过下标索引取出对应位置的数据 |
运行结果
1 | Tom |
列表的常用操作方法
列表除了可以:定义、使用下标索引获取值以外,列表也提供了一系列功能
- 插入元素
- 删除元素
- 清空列表
- 修改元素
- 统计元素个数
这些功能我们都称之为:列表的方法
函数是一个封装的代码单元,可以提供特定功能
在python中,如果将函数定义为class(类)的成员,那么函数会称之为:方法
方法和函数功能一样,有传入参数,有返回值,只是方法的使用格式不同
查找某元素的下标
功能:查找指定元素在列表的下标,如果找不到,报错ValueError
语法:列表.index(元素)
index就是列表对象(变量)内置的方法(函数)
插入元素
语法:列表.insert(下标,元素),在指定的下标位置,插入指定的元素
追加元素
语法:列表.append(下标,元素),将指定的元素,追加到列表的尾部
追加元素方式2
语法:列表.extend(其他数据容器),将其他数据容器的内容取出,依次追加到列表尾部
删除元素
语法1:del 列表[下标]
语法2:列表.pop(下标)
删除某元素在列表中的第一个匹配项
语法:列表.remove(元素)
清空列表内容
语法:列表.clear()
统计某元素在列表内的数量
语法:列表.count(元素)
统计列表内,有多少元素
语法:len(列表)
可以得到一个int数字,表示列表内的元素数量
Demo1
1 | """ |
运行结果
1 | hello在列表中的下标索引值是:0 |
列表的特点
- 可以容纳多个元素(上限为2**63-1、9223372036854775807个)
- 可以容纳不同类型的元素(混装)
- 数据是有序存储的(有下标序号)
- 允许重复数据存在
- 可以修改(增加或删除元素等)
Demo2
1 | """ |
运行结果
1 | 从列表中取出来第一个元素,应该是21,实际上是:21 |
列表的循环遍历
列表的遍历-while循环
既然数据容器可以存储多个元素,那么,就会有需求从容器内依次取出元素进行操作。将容器内的元素依次取出处理的行为,称之为:遍历、迭代
如何遍历列表的元素呢?-可以使用前面学过的while循环
如何在循环中取出列表的元素呢?-使用列表[下标]的方式取出
循环条件如何控制?
- 定义一个变量表示下标,从0开始
- 循环条件为 下标值<列表的元素数量
列表的循环-for循环
除了while循环外,Python中还有另外一种循环形式:for循环。
对比while,for循环更加适合对列表等数据容器进行遍历。
语法:
1 | for 临时变量 in 数据容器: |
表示,从容器内,依次取出元素并赋值到临时变量上。
在每一次的循环中,我们可以对临时变量(元素)进行处理。
while循环和for循环的对比
while循环和for循环,都是循环语句,但细节不同:
- 在循环控制上:
- while循环可以自定义循环条件,并自行控制
- for循环不可以自定循环条件,只可以一个个从容器内取出数据
- 在无限循环上:
- while循环可以通过条件控制做到无限循环
- for循环理论上不可以,因为被遍历的容器容量不是无限的
- 在使用场景上:
- while循环使用于任何想要循环的场景
- for循环使用于,遍历数据容器的场景或简单的固定次数循环场景
Demo
1 | """ |
运行结果
1 | 列表的元素:hello |
元组的定义和操作
元组和列表一样,都是可以封装多个、不同类型的元素在内,但最大的不同点在于:元组一旦定义完成,就不可修改
所以,当我们需要在程序内封装数据,又不希望封装的数据被篡改,那么元组就非常合适了
定义元组
元组定义:定义元组使用小括号,且使用逗号隔开各个数据,数据可以是不同的数据类型。
1 | #定义元组字面量 |
元组也支持嵌套:
1 | # 定义一个嵌套元组 |
注意事项:
1 | # 定义3个元素的元组 |
注意:元组只有一个数据,这个数据后面要添加逗号
编号 | 方法 | 作用 |
---|---|---|
1 | index() | 查找某个数据,如果数据存在返回对应的下标,否则报错 |
2 | count() | 统计某个数据在当前元组出现的次数 |
3 | len(元组) | 统计元组内的元素个数 |
1 | # 根据下标(索引)取出数据 |
元组的相关操作-注意事项
- 不可以修改元组的内容,否则会直接报错
- 可以修改元组内的list的内容(修改元素、增加、删除、反转等)
Demo
1 | """ |
运行结果
1 | t1的类型是:<class 'tuple'>,内容是:(1, 'Hello', True) |
字符串的定义和操作
字符串的下标(索引)
和其他容器如:列表、元组一样,字符串也可以通过下标进行访问
- 从前向后,下标从0开始
- 从后向前,下标从-1开始
1 | # 通过下标获取特定位置字符 |
同元组一样,字符串是一个:无法修改的数据容器
所以:
- 修改指定下标的字符(如:字符串[0]=”a”)
- 移除特定下标的字符(如:del字符串[0]、字符串.remove()、字符串.pop()等)
- 追加字符等(如:字符串.append())
均无法完成。如果必须要做,只能得到一个新的字符串,旧的字符串无法修改
字符串的常用操作
查找特定字符串的下标索引值
语法:字符串.index(字符串)
1
2my_str = “itcast and itheima"
print(my_str.index("and")) # 结果7字符串的替换
语法:字符串.replace(字符串1, 字符串2)
功能:将字符串内的全部:字符串1,替换为字符串2
注意:不是修改字符串本身,而是得到了一个新字符串
字符串的分割
语法:字符串.split(分隔符字符串)
功能:按照指定的分隔符字符串,将字符串划分为多个字符串,并存入列表对象中
注意:字符串本身不变,而是得到了一个列表对象
字符串的规整操作(去前后空格)
语法:字符串.strip()
1
2my_str = " itheima and itcast "
print(my_str.strip()) #结果:"itheima and itcast"字符串的规整操作(去前后指定字符串)
语法:字符串.strip(字符串)
1
2my_str = "12itheima and itcast21"
print(my_str.strip("12")) #结果:"itheima and itcast"注意,传入的是“12”其实就是:“1”和“2”都会移除,是按照单个字符。
字符串常用操作汇总
编号 | 操作 | 说明 |
---|---|---|
1 | 字符串[下标] | 根据下标索引取出特定位置字符 |
2 | 字符串.index(字符串) | 查找给定字符的第一个匹配项的下标 |
3 | 字符串,replace(字符串1,字符串2) | 将字符串内全部字符串1,替换为字符串2 不会修改原字符串,而是得到一个新的 |
4 | 字符串.split(字符串) | 按照给定字符串,对字符串进行分隔 不会修改原字符串,而是得到一个新的列表 |
5 | 字符串.strip() 字符串.strip(字符串) |
移出首尾的空格和换行符或指定字符串 |
6 | 字符串.count(字符串) | 统计字符串内某字符串的出现次数 |
7 | len(字符串) | 统计字符串的字符个数 |
字符串的遍历
同列表、元组一样,字符串也支持while循环和for循环进行遍历
1 | my_str = "Python" |
1 | my_str = "Python" |
运行结果都为:
1 | P |
字符串的特点
作为数据容器,字符串有如下特点:
- 只可以存储字符串
- 长度任意(取决于内存大小)
- 支持下标索引
- 运行重复字符串存在
- 不可以修改(增加或删除元素等)
- 支持for循环
Demo
1 | """ |
运行结果
1 | 从字符串itheima and itcast去下标为2的元素,值是:h,取下标为-16的元素,值是:h |
Demo2
1 | """ |
运行结果
1 | 字符串itheima itcast bouxuegu中有2个it字符 |
数据容器(序列)的切片
序列
序列是指:内容连续、有序,可使用下标索引的一类数据容器
列表、元组、字符串、均可以视为序列
序列的常用操作-切片
序列支持切片,即:列表、元组、字符串、均支持进行切片操作
切片:从一个序列中,取出一个子序列
语法:序列[起始下标;结束下标;步长]
表示从序列中,从指定位置开始,依次取出元素,到指定位置结束,得到一个新序列:
- 起始下标表示从何处开始,可以留空,留空视作从头开始
- 结束下标(不含)表示何处结束,可以留空,留空视作截取到结尾
- 步长表示,依次取元素的间隔
- 步长1表示,一个个取元素
- 步长2表示,每次跳过1个元素取
- 步长N表示,每次跳过N-1个元素取
- 步长为负数表示,反向取(注意,起始下标和结束下标也要反向标记)
Demo
1 | """ |
运行结果
1 | 结果1:[1, 2, 3] |
Demo2
1 | """ |
运行结果
1 | 方式1结果:黑马程序员 |
集合的定义和操作
集合的定义
基本语法:
1 | # 定义集合字面量 |
和列表、元组、字符串等定义基本相同:
- 列表使用:[]
- 元组使用:()
- 字符串使用:””
- 集合使用:{}
集合的常用操作-修改
首先,因为集合是无序的,所以集合不支持:下标索引访问
但是集合和列表一样,是允许修改的,所以我们来看看集合的修改方法。
添加新元素
语法:集合.add(元素)。将指定元素,添加到集合内
结果:集合本身被修改,添加了新元素
1
2
3my_set = {"Hello", "World"}
my_set.add("itheima")
print(my_set) #结果{'Hello', 'itheima', 'World'}移除元素
语法:集合.remove(元素),将指定元素,从集合内移除
结果:集合本身被修改,移除了元素
1
2
3my_set = {"Hello", "World"}
my_set.add("Hello")
print(my_set) #结果{'World'}从集合中随机取出元素
语法:集合.pop(),功能,从集合中随机取出一个元素
结果:会得到一个元素的结果。同时集合本身被修改,元素被移除
1
2
3
4my_set = {"Hello", "World", "itheima"}
element = my_set.pop()
print(my_set) #结果{'World', 'itheima'}
print(element) #结果'Hello'清空集合
语法:集合.clear(),功能,清空集合
结果:集合本身被清空
1
2
3my_set = {"Hello", "World", "itheima"}
my_set.clear()
print(my_set) #结果:set() 空集合取出2个集合的差集
语法:集合1.difference(集合2),功能:取出集合1和集合2的差集(集合1有而集合2没有的)
结果:得到一个新集合,集合1和集合2不变
1
2
3
4
5
6set1 = {1, 2, 3}
set2 = {1, 5, 6}
set3 = set1.difference(set2)
print(set3) #结果:{2, 3} 得到的新集合
print(set1) #结果:{1, 2, 3}不变
print(set2) #结果:{1, 5, 6}不变消除2个集合的差集
语法:集合1.difference_update(集合2)
功能:对比集合1和集合2,在集合1内,删除和集合2相同的元素
结果:集合1被修改,集合2不变
1
2
3
4
5set1 = {1, 2, 3}
set2 = {1, 5, 6}
set1.difference_update(set2)
print(set1) #结果:{2, 3}
print(set2) #结果:{1, 5, 6}2个集合合并
语法:集合1.union(集合2)
功能:将集合1和集合2组合成新集合
结果:得到新集合,集合1和集合2不变
1
2
3
4
5
6set1 = {1, 2, 3}
set2 = {1, 5, 6}
set3 = set1.union(set2)
print(set3) #结果:{1, 2, 3, 5, 6},新集合
print(set1) #结果:{1, 2, 3},set1不变
print(set2) #结果:{1, 5, 6},set2不变
编号 | 操作 | 说明 |
---|---|---|
1 | 集合.add(元素) | 集合内添加一个元素 |
2 | 集合.remove(元素) | 移除集合内指定的元素 |
3 | 集合.pop() | 从集合中随机取出一个元素 |
4 | 集合.clear() | 将集合清空 |
5 | 集合1.difference(集合2) | 得到一个新集合,内含2个集合的差集 原有的2个集合内容不变 |
6 | 集合1.difference_update(集合2) | 在集合1中,删除集合2中存在的元素 集合1被修改,集合2不变 |
7 | 集合1.union(集合2) | 得到1个新集合,内含2个集合的全部元素 原有的2个集合内容不变 |
8 | len(集合) | 得到一个整数,记录了集合的元素数量 |
集合的特点
- 可以容纳多个数据
- 可以容纳不同类型的数据(混装)
- 数据是无序存储的(不支持下标索引)
- 不允许重复数据存在
- 可以修改(增加或删除元素等)
- 支持for循环
Demo
1 | """ |
运行结果
1 | my_set的内容是:{'传智教育', '黑马程序员', 'itheima'},类型是:<class 'set'> |
Demo2
1 | """ |
运行结果
1 | 列表的内容是:['黑马程序员', '传智博客', '黑马程序员', '传智博客', 'itheima', 'itcast', 'itheima', 'itcast', 'best'] |
字典的定义
字典的定义
字典的定义,同样使用{},不过存储的元素是一个个的:键值对,如下语法:
1 | # 定义字典字面量 |
字典内Key不允许重复,重复添加等同于覆盖原有数据
字典数据的获取
字典同集合一样,不可以使用下标索引
但是字典可以通过Key值来取得对应的Value
1 | # 语法,字典[Key]可以取到对应的Value |
字典的嵌套
字典的Key和Value可以是任意数据类型(Key不可为字典)
那么,就表明,字典是可以嵌套的
需求如下:记录学生各科的考试信息
Demo
1 | """ |
运行结果
1 | 字典1的内容是:{'王力鸿': 99, '周杰轮': 88, '林俊节': 77},类型:<class 'dict'> |
字典的常用操作
新增元素
语法:字典[Key] = Value,结果:字典被修改,新增了元素
1
2
3
4
5
6
7
8stu_score = {
"王力鸿": 77,
"周杰轮": 88,
"林俊节": 99
}
# 新增:张学油的考试成绩
stu_score['张学油'] = 66
print(stu_score) # 结果:{'王力鸿': 77, '周杰轮': 88, '林俊节': 99, '张学油': 66}更新元素
语法:字典[Key]=Value,结果:字典被修改,元素被更新
注意:字典Key不可以重复,所以对已存在的Key执行上述操作,就是更新Value值
1
2
3
4
5
6
7
8stu_score = {
"王力鸿": 77,
"周杰轮": 88,
"林俊节": 99
}
#更新:王力鸿的考试成绩
stu_score['王力鸿'] = 100
print(stu_score) #结果:{'王力鸿': 100, '周杰轮': 88, '林俊节': 99}删除元素
语法:字典.pop(Key),结果:获得指定Key的Value,同时字典被修改,指定Key的数据被删除
1
2
3
4
5
6
7
8stu_score = {
"王力鸿": 77,
"周杰轮": 88,
"林俊节": 99
}
value = stu_score.pop("王力鸿")
print(value) # 结果:77
print(stu_score) # 结果:{'周杰轮': 88, '林俊节': 99}清空字典
语法:字典.clear(),结果:字典被修改,元素被清空
1
2
3
4
5
6
7stu_score = {
"王力鸿": 77,
"周杰轮": 88,
"林俊节": 99
}
stu_score.clear()
print(stu_score) # 结果:{}获取全部的key
语法:字典.keys(),结果:得到字典中的全部Key
1
2
3
4
5
6
7stu_score = {
"王力鸿": 77,
"周杰轮": 88,
"林俊节": 99
}
keys = stu_score.keys()
print(keys) # 结果:dict_keys(['王力鸿', '周杰轮', '林俊节']}
字典的常用操作总结
编号 | 操作 | 说明 |
---|---|---|
1 | 字典[Key] | 获取指定Key对应的Value值 |
2 | 字典[Key] = Value | 添加或更新键值对 |
3 | 字典.pop(Key) | 取出Key对应的Value并在字典内删除此Key的键值对 |
4 | 字典.clear() | 清空字典 |
5 | 字典.keys() | 获取字典的全部Key,可用于for循环遍历字典 |
6 | len(字典) | 计算字典内的元素数量 |
字典的特点
- 可以容纳多个数据
- 可以容纳不同类型的数据
- 每一行数据是KeyValue键值对
- 可以通过Key获取到Value,Key不可重复(重复会覆盖)
- 不支持下标索引
- 可以修改(增加或删除更新元素等)
- 支持for循环,不支持while循环
Demo
1 | """ |
运行结果
1 | 字典经过新增元素后,结果:{'周杰轮': 99, '林俊节': 88, '张学油': 77, '张信哲': 66} |
Demo2
1 | """ |
运行结果
1 | 员工在升值加薪之前的结果:{'王力鸿': {'部门': '科技部', '工资': 3000, '级别': 1}, '周杰轮': {'部门': '市场部', '工资': 5000, '级别': 2}, '林俊节': {'部门': '市场部', '工资': 7000, '级别': 3}, '张学油': {'部门': '科技部', '工资': 4000, '级别': 1}, '刘德滑': {'部门': '市场部', '工资': 6000, '级别': 2}} |
5类数据容器的总结与对比
数据容器分类
数据容器可以从一下视角进行简单的分类:
- 是否支持下标索引
- 支持:列表、元组、字符串 - 序列类型
- 不支持:集合、字典 - 非序列类型
- 是否支持重复元素:
- 支持:列表、元组、字符串 - 序列类型
- 不支持:集合、字典 - 非序列类型
- 是否可以修改:
- 支持:列表、集合、字典
- 不支持:元组、字符串
数据容器特点对比
列表 | 元组 | 字符串 | 集合 | 字典 | |
---|---|---|---|---|---|
元素数量 | 支持多个 | 支持多个 | 支持多个 | 支持多个 | 支持多个 |
元素类型 | 任意 | 任意 | 仅字符 | 任意 | Key: Value Key:除字典外任意类型 Value:任意类型 |
下标索引 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
重复元素 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
可修改性 | 支持 | 不支持 | 不支持 | 支持 | 支持 |
数据有序 | 是 | 是 | 是 | 否 | 否 |
使用场景 | 可修改、可重复的一批数据记录场景 | 不可修改、可重复的一批数据记录场景 | 一串字符的记录场景 | 不可重复的数据记录场景 | 以Key检索Value的数据记录场景 |
基于各类数据容器的特点,它们的应用场景如下:
- 列表:一批数据,可修改、可重复的存储场景
- 元组:一批数据,不可修改、可重复的存储场景
- 字符串:一串字符串的存储场景
- 集合:一批数据,去重存储场景
- 字典:一批数据,可用Key检索Value的存储场景
数据容器的通用操作
数据容器的通用操作 - 遍历
数据容器尽管各自有各自的特点,但是它们也有通用的一些操作
首先,在遍历上:
- 5类数据容器都支持for循环遍历
- 列表、元组、字符串支持while循环,集合、字典不支持(无法下标索引)
尽管遍历的形式各有不同,但是,它们都支持遍历操作
数据容器的通用统计功能
除了遍历这个共性外,数据容器可以通用非常多的功能方法
len(容器)
统计容器的元素个数
1
2
3
4
5
6my_list = [1, 2, 3]
my_tuple = (1, 2, 3, 4, 5)
my_str = "itheima"
print(len(my_list)) # 结果3
print(len(my_tuple)) # 结果5
print(len(my_str)) # 结果7max(容器)
统计容器的最大元素
1
2
3
4
5
6my_list = [1, 2, 3]
my_tuple = (1, 2, 3, 4, 5)
my_str = "itheima"
print(max(my_list)) # 结果3
print(max(my_tuple)) # 结果5
print(max(my_str)) # 结果tmin(容器)
统计容器的最小元素
1
2
3
4
5
6my_list = [1, 2, 3]
my_tuple = (1, 2, 3, 4, 5)
my_str = "itheima"
print(min(my_list)) # 结果1
print(min(my_tuple)) # 结果1
print(min(my_str)) # 结果a
容器的通用转换功能
除了下标索引这个共性外,还可以通用类型转换
list(容器)将给定容器转换为列表
str(容器)将给定容器转换为字符串
tuple(容器)将给定容器转换为元组
set(容器)将给定容器转换为集合
容器通用排序功能
通用排序功能
sorted(容器, [reverse=True])
将给定容器进行排序
容器通用功能总览
功能 | 描述 |
---|---|
通用for循环 | 遍历容器(字典是遍历key) |
max() | 容器内最大元素 |
min() | 容器内最小元素 |
len() | 容器元素个数 |
list() | 转换为列表 |
tuple() | 转换为元组 |
str() | 转换为字符串 |
set() | 转换为集合 |
sorted(序列, [reverse = True]) | 排序,reverse = True表示降序 得到一个排好序的列表 |
Demo
1 | """ |
运行结果
1 | 列表 元素个数有:5 |
拓展-字符串大小比较的方式
字符串如何比较
从头到尾,一位位进行比较,其中一位大,后面就无需比较了
单个字符之间如何确定大小?
通过ASCII码表,确定字符对应的码值数字来确定大小
Demo
1 | """ |
运行结果
1 | abd大于abc,结果:True |