6. 数据容器
什么是?
一种能存放多个数据的数据类型
数据容器可以更高效的管理成批的数据,且便于存储、访问
容器中的每一个数据,又称为元素
python 中有很多种数据容器: 列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)
下标(索引值)
就是列表中元素的位置编号
正索引:从左往右数,起始元素是0,随后是1,依次类推
负索引:从右往左数,起始元素是-1,随后是-2, 依次类推
list4 = [23, '横州', False, [1, 2, 3]]
print(list4[1]) # 横州
print(list4[-1]) # [1, 2, 3]数据容器常用内置函数
不单单是列表、其它容器数据的也能生效
排序 sorted
对容器排序(默认从小到大,不会改变原容器)
语法:sorted(数据容器, reverse=布尔值)
返回值:经过排序的新容器
PS: 字符串比较的是unicode码
元素个数 len
获取容器中元素的个数
语法:len (数据容器变量名)
返回值:元素个数
最大值 max
返回容器中或多个值中的最大值
语法: max(数据容器变量名)
返回值:最大值
PS: 字符串比较的是unicode码
最小值 min
返回容器中或多个值中的最小值
语法: min(数据容器变量名)
返回值:最小值
PS: 字符串比较的是unicode码
元素求和 sum
对容器中的所有元素进行求和(只能是数值类型)
语法:sum(数据容器变量名)
返回值:所有元素的和
成员运算符: in / not in
所有的数据容哒哒,都支持成员运算符,用来判断某个元素是否在容器中
di = {
'name': '张三',
'age': 25,
'isMan': True
}
l1 = [1, 2, 3]
print( 'name' in di )
print (1 in l1)容器中的遍历
# while
index = 0
list4 = [23, '横州', False, [1, 2, 3]]
while index < len(list4):
print(list4[index])
index += 1
print('------')
# for
for item in list4:
print(item)
print('------')
# 写法1 和for循环一致
for item in range(len(list4)):
print(list4[item])
print('------')
# 写法3 可以取出item 和 index
for index, item in enumerate(list4, start=0):
print(index, item)序列的切片操作
PS: 其实就类似于js中的分割数组并返回新数组一样
序列:可以是列表、元组、字符串都是序列
切片:从序列中按照指定范围,取出一部分元素,形成一个新序列的操作
语法:序列变量名[起始索引:结束索引:步长]
当起始索引大于结束索引时,步长必须为负数、否则结果是空列表。
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
print(list1[::]) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
# 一个特殊情况:当同时省略起始和结束索引时,如果步长为负数,那py会自动对调
print(list1[::-1]) # [11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
print(list1[::2]) # [1, 3, 5, 7, 9, 11]
print(list1[1:5:2]) # [2, 4]
print(list1[:2:]) # [1, 2]序列的其它特殊操作
list1 = [1, 2, 3]
print(list1 + [3, 4, 5]) # [1, 2, 3, 3, 4, 5]
print(list1 * 3) # [1, 2, 3, 1, 2, 3, 1, 2, 3]
print ('hello' + ' world') # hello world
print('hello' * 2) # hellohello列表(list)
定义列表
list1 = [34, 56, 31]
list2 = ['广西', '横州', 'huangcy']
list3 = [23, '横州', True]
list4 = [23, '横州', False, [1, 2, 3]]
list5 = []
list6 = list()list()可以将任意可迭代对象转换成列表(如range 、字符串、字典、 集合)
修改操作
列表变量名[下标] = 新值
查询操作
列表变量名[下标]
列表变量名[下标][下标] # 二级嵌套的元素
# 更方便的取值方法
l1 = ['haungcy', '男', 25]
name, gender, age = l1
print(name, age) # huangcy 25列表内置常用方法
新增 append
列表变量名.append(元素
list4 = [23, '横州', False, [1, 2, 3]]
list4.append('追加元素')
print(list4)插入元素 insert
列表变量名.insert(下标, 元素)
可迭代对象 extend
extend() 用于把另一个可迭代对象里的元素逐个追加到当前列表末尾。
a = [1, 2, 3]
a.extend([4, 5, 6])
print(a)删除pop
删除指定位置的元素,并将删除的元素返回。
语法:列表变量名.pop(下标)
删除remove
删除列表中第一次出现的指定值。
语法:列表变量名.remove(值)
清空列表 clear
删除列表中的所有元素(变成一个空列表)
语法:列表变量名.clear()
删除指定位置元素 del
语法:列表变量名[下标]
查找元素第一次出现的下标 index
返回:元素下标
语法:列表变量名.index(值)
注意:如果不存在的元素,直接报错,垃圾py
统计元素个数 count
统计某个元素在列表中出现的次数
返回值:元素出现的次数
语法:列表变量名.count(值)
反转列表 reverse
反转列表(会改变原列表)
列表变量名.reverse()
列表排序 sort
对列表排序(默认从小到大,会改变原列表、传入reverse=True时,就会变成从大到小)
语法:列表变量名.sort(reverse=布尔值)
若列表中有数字、又有字符串,就会报错;如果都是字符串,按,unicode编码大小进行排序
元组(tuple)
元组是一种和列表类似的数据容器,它和列表的区别是:元组中的元素不可修改
如果元组中的元素为列表,还是可以修改的
定义只有一个元素的元素、后面必须加一个字符串,否则会认为是字符串
定义元组
tuple1 = (1, 2, 3)
tuple2 = () # 定义空元组
tuple3 = tuple() # 定义空元组
typele6 = tuple(list1) # 可以转入一个列表转换成元组
tuple4 = ('只有一个元素',) # 定义只有一个元素的元素、后面必须加一个字符串,否则会认为是字符串
print(tuple1)tuple()可以将任意可迭代对象转换成元组(如range 、字符串、字典、 集合)
获取元素
tuple1[下标]
tuple1[下标][下标]常用方法
查找元素第一次出现的下标 index
返回:元素下标
语法:元组变量名.index(值)
注意:如果不存在的元素,直接报错,垃圾py
统计元素个数 count
统计某个元素在元组中出现的次数
返回值:元素出现的次数
语法:元组变量名.count(值)
列表与元组通过参数进行打包传递
def fun(*args):
"""
测试函数
:param args: 接收N个参数、是一个元组
:return:
"""
print(args)
list1 = [1, 2, 3, 4, 5]
tuple2 = (6, 7, 8, 9, 10)
fun(*list1) # 相当于传递5个参数: 1, 2, 3, 4, 5
fun(*tuple2) # 相当于传递5个参数: 6, 7, 8, 9, 10字符串(str)
从数据容器的角度:字符串就是存放多个字符的容器
字符串的下标,每个字符一个下标
定义字符串
hello = '我是字符串'
s = str()
s1 = str("hell0")str函数可以将任意类型转换成字符串
常用方法
查找元素第一次出现的下标 index
返回:元素下标
语法:变量名.index(值)
注意:如果不存在的元素,直接报错,垃圾py
按指定字符 split
返回:返回一个新的列表
语法:变量名.split(值)
替换字符串 replace
返回:返回一个新的字符串
语法:变量名.replace(原值, 新值)
统计指定字符次数 count
统计字符串的数量
返回值:数量
语法:变量.count(值)
strip
常用:用来清空两边的字符串,此时可以不传参

集合 (set / frozenset)
分为可变集合(set)和不可变集合,可合集合可以增删元素,不可变集合不能增删元素
集合的特点:
- 无序:集合中的元素没有固定顺序,无法通过下标访问
- 不重复:集合会自动去重,同一个元素只会保留一份
- 分成可变集合和不可变集合
- 集合同的元素必须是不可变类型(如数字、字符串、元组)
- 集合支持:并集、交集、差集、对称差集等数学操作
集合中不能嵌套可变集合,但可以嵌套不可变集合(原因: 集合不支持下标,但底层依然需要给其中的每个元素,分配一个“编号”,这个编号可以用来快速定位元素,并且这个编号是哈希值。而哈希值是根据内容计算出来的,内容一旦发生变化,对于集合来说,元素的哈希值一旦变化,就无法再通过原来的哈希值找到这个元素)
可变集合(set)的定义
set1 = { 1, 2, 3, True }
print(set1) # {1, 2, 3} True用的是1存储,有重复的会去掉,False 0 同理、也可能保留True,去掉1
# 定义空集合
s1 = set()set()可以将任意可迭代对象转换成集合(如range 、字符串、字典、 集合)
不可变集合(frozenset)的定义
不可变集合 frozenset 可以接收任何可迭代的变量
set1 = frozenset({ 1, 2, 3, True })
print(set1) # frozenset({1, 2, 3})
f = frozenset([1, 2, 3 ]) # 接收任意可对迭代对象
# 空义不可变空集合
f = frozenset()集合.add(元素)
向集合中添加元素
返回值:无
集合.update(元素)
向集合中批量添加元素(接收可迭代对象,例如:列表、元组、集合等)
集合.remove(元素)
从集合中移除指定元素(若元素不存在,会报错)
返回值:无
集合.discard(元素)
从集合中移除指定元素(若元素不存在,不会报错)
返回值:无
集合.pop()
从集合中移除一个任意元素
返回值:移除的元素
集合.clear()
清空集合
返回值:无
其它注意
集合中没有专门用修改的方法,可以用上面的方法配合达到相同的目的
集合没有下标,也就不能进行切片操作
常用方法
集合A.difference(集合B)
找出集合A中,不同于集合B的元素(集合A与集合B都不变)
返回值:一个新的集合
集合A.difference_update(集合B)
从集合A中,删除集合B存在的元素(集合A被修改,集合B不会)
返回值:一个新的集合
集合A.union(集合B)
合并两个集合(两个集合都不会被修改)
返回值:一个新的集合
集合A.issubset(集合B)
判断集合A是否为集合B的子集
规则: 如果集合A中的所有元素,都在集合B中,那就返回True, 否则返回False
返回值:布尔值
集合A.issuperset(集合B)
判断集合A是否是集合B的超集
规则: 如果集合A中,包含了集合B中的所有元素,那就返回True,否则返回False
返回值:布尔值
集合A.isdisjoint(集合B)
判断集合A和集合B是否没有交集
规则: 如果没有交集,那就返回True,但凡有一个公共元素,就返回False
返回值:布尔值
集合的数学运算

集合的循环遍历
集合不能使用while循环直接遍历,但可以使用for 循环进行遍历
原因:while循环需要通过下标访问元素,而集合是无序的,没有下标的
字典(dict)
键(key) 与值(value)的对应关系
字典可以嵌套
特点:
- 键值对结果:字典中的数据以key:value的形式存,每个键都对应一个值。
- 键唯一:字典中的键(key)不能重复,若重复则后写的会覆盖前面写的。
- 键不可变:键必须是不可变类型(如数字、字符串、元组等),而值可以是任意类型
- 不支持下标:字典中的元素不能通过下标取值
- 支持增删改查,支持for循环遍历
定义字典
# 字典中的key不能重复,若重复,则会覆盖
d2 = {}
d3 = dict()
d1 = { 'name': '张三', 'age': 25, 'isMan': True }
print(d1)dict()可以将任意可迭代对象转换成字典(如range 、字符串、字典、 集合)
字典的增删改查
di = {
'name': '张三',
'age': 25,
'isMan': True
}
# 查询(不存在则报错)
print(di['name'])
print(di['age'])
print(di['isMan'])
print("-----------")
# 查询(不存在也不会报错)
print(di.get('isMan'))
print(di.get('age'), 25) # 如果key不存在,25就是默认值
# 新增
di['height'] = 178
# 修改 (和新增一样,有key则是修改,没key则是新增)
di['height'] = 178
# 批量修改
di.update({ 'name': 'huangcy', 'age': 30, 'width': 155 })
print(di)
# 删除
# 方式1
del di['name']
# 方式2
res = di.pop('age')
print(res)
# pop 删除默认删除不存在的key时,会删除失败;可以传入第二个参数
res1 = di.pop('222', 'ok')
print(res1, 'pop 第二个参数')
# 清空
di.clear()
print(di)字典的常用方法
# 获取字典中所有的key
keys = di.keys()
print(keys, type(keys))
# 返回值keys不是list,而是一种叫做dict_keys的类型、和list类似,可以被遍历,但要注意的是:它不能通过下标访问
# 获取字典中所有的value、返回类型是dict_values
values = di.values()
print(values, type(values))
# 获取字典中所有的键值对
items = di.items()
print(items, type(items))字典遍历
字典不能使用while循环遍历,可以使用for 循环遍历
di = {
'name': '张三',
'age': 25,
'isMan': True
}
for key in di:
print(key)
# name
# age
# isMan
for key in di.keys():
print(key)
# name
# age
# isMan
for item in di.items():
print(item)
# ('name', '张三')
# ('age', 25)
# ('isMan', True)综合练习
# 练习一: 水果清单
fruits = {
'苹果': 4.5,
'香焦': 3.2,
'橙子': 5.8,
'草莓': 12.0,
'哈密瓜': 8.8
}
# 需求1: 打印所有的水果
for item in fruits:
print(item)
# 需求2: 找出最贵的水果
key = max(fruits, key=fruits.get)
print(f'{key}最贵的水果是,{fruits[key]}元/斤')# 需求2: 找到总分最高的学生
def find_bast():
best_students = []
best_score = 0
for stu in students:
total = sum(stu['scores'].values())
if total > best_score:
best_score = total
best_students = [stu['name']]
elif total == best_score:
best_students.append(stu['name'])
print(f'当前最高分{total}, 最高分的学生有:{best_students}')
find_bast()# 练习三: 评论内容
comment = '这家奶茶真好喝,环境也不错,就是价格有点贵,好喝好喝好喝!强烈推荐!'
# 需求1: 统计“好喝”出现次数
print(comment.count('好喝'))
# 需求2: 将字符串中的“贵”替换为“略高”
print(comment.replace('贵', '略高'))
# 需求3: 是否包含“推荐”2个字
print('推荐' in comment)总结

