Python 容器

190 阅读18分钟

遍历

遍历概念: 从容器中把元素一个个取出的过程

遍历方式: for 循环 和 while 循环

for 循环:

for 循环不支持无限循环
所有容器都支持for循环, 因为for循环又叫遍历循环
for循环时提前准备好数据集,无需手动做条件控制
for循环的变量是临时变量,作用域仅限于for循环内部(注意:python中循环报黄不报错)

while循环:

while循环支持无限循环
部分容器不支持while循环遍历, 因为部分容器没有下标索引
while循环需要定义初始变量并且手动做条件控制
while循环的变量是全局变量,作用域是所有循环的内外都可以使用

使用场景上:

while循环适用于任何想要循环的场景
for循环适用于, 遍历数据容器的场景或简单的固定次数循环场景

容器

==容器==: 能存储多个元素的python类型,就是容器

==元素==: 容器中的每份数据

==方法==: 本质就是函数==,在Python中, 如果将函数定义为class(类)的成员, 那么函数会称之为: 方法

==5种容器==: 列表(list)  元组(tuple) 字符串(str)  集合(set)  字典(dict)

列表[重点]

==列表==(list)是可变类型

列表的定义:

知识点:

定义空列表:
    方式1(常用): 列表名 = []
    方式2 : 列表名 = list()
    
定义非空列表:
    方式1:(常用): 列表名 = [元素1, 元素2, ...]
    方式2 : 列表名 = [[元素1, 元素2], [元素1, 元素2], ...]

示例

# 1.定义空列表
list1 = []
print(list1)
# 注意: 可以使用类型()方式定义空列表
list2 = list()
print(list2)

# 2.定义非空列表
list3 = ['张三', '李四', '王五', ...]
print(list3)
# 注意:列表可以存储不同类型数据,但是不建议
list4 = ['张三', 10, 3.14, True, None]
print(list4)
# 定义嵌套列表
big_list = [list1, list2, list3, list4]
print(big_list)

列表的下标索引

知识点:

下标索引: 本质就是每个元素对应的编号, 但是需要主义的是有两套索引

正索引: 从前到后, 从0开始,依次递增

负索引: 从后到前, 从-1开始, 依次递减

根据索引找元素: 列表名[索引]

列表中最大索引: len(列表)-1

注意: 如果访问了不存在的索引就会报:索引界异常(IndexError: list index out of range)

示例1:

# 需求1: 定义一个列表,存储'张三', '李四', '王五', '赵六'
name_list = ['张三', '李四', '王五', '赵六']
print(name_list)

# 需求2: 查找并打印出第一个元素
# 方式1: 正索引(建议)
name = name_list[0]
print(name)
# 方式2: 负索引
name = name_list[-4]
print(name)

# 需求3: 查找并打印出最后一个元素
# 方式1: 正索引
print(name_list[3])
# 方式2: 负索引(建议)
print(name_list[-1]

示例2:

"""
需求:已知张三的年龄18, 李四的年龄28, 王五的年龄38, 要求定义两个列表, 分别存储姓名和年龄后,放到一个大info列表中
最后从info列表中查找元素打印效果如下:
张三:18
李四:28
王五:38
"""
# 定义两个列表, 分别存储姓名和年龄
name_list = ['张三', '李四', '王五']
age_list = [18, 28, 38]
# info嵌套两个小列表
info= [name_list, age_list]
# 先根据索引获取原色, 然后字符串格式化输出
print(f'{info[0][0]} : {info[1][0]}')
print(f'{info[0][1]} : {info[1][1]}')
print(f'{info[0][2]} : {info[1][2]}')

列表的增删改查操作

添加元素(增)

添加一个元素到列表末尾: 列表名.append(元素)

添加多个元素到列表末尾: 列表名.extend(容器)

在指定位置插入指定元素: 列表名.insert(索引位置,元素)

# 需求: 定义一个空列表,依次使用三种添加元素方法给列表添加数据
# 1.定义空列表
name_list = []

# 2.使用append分别添加张三,李四到列表中
name_list.append('张三')
name_list.append('李四')

# 3.使用extend一次性添加多个元素到列表中
name_list.extend(['王五','赵六'])

# 4.使用insert插入数据到指定位置
nam_list.insert(0,'老大')
print(name_list)

删除元素(删)

根据索引删除对应位置上的元素: 列表名:pop(索引) 或者 del 列表名[索引]

直接删除指定元素: 列表名.remove(元素)

清空列表所有元素: 列表名.clear()

练习:
# 需求: 已知列表['老大', '张三', '李四', '王五', '赵六'],使用多种删除元素方式完成删除
# 1.定义非空列表
name_list = ['老大', '张三', '李四', '王五', '赵六']
print(name_list)

# 2.删除第一个元素
name_list.pop(0)
print(name_list)

# 3.删除最后一个元素
del name_list[-1]
print(name_list)

# 4.删除'王五'元素
name_list.remove('王五')
print(name_list)

# 5.清空列表
name_list.clear()
print(name_list)

修改元素

根据索引修改指定位置上的元素: 列表名[索引] = 新值

练习: 
# 需求1: 已知列表中存储了张三,李四, 王五,要求把李四修改成赵六
# 1.定义列表存储张三,李四, 王五
name_list = ['张三', '李四', '王五']
print(name_list)
# 2.把李四修改成赵六
name_list[1] = '赵六'
print(name_list)

# 需求2: 已知大列表中存储了姓名列表
big_list =[['张三', '赵六', '王五'], [18, 28,38]]
print(big_list)
# 把王五改成周七
big_list[0][2] = '周七'
print(big_list)

查询元素(查)

根据索引查询指定位置上的元素: 列表名[索引]

查询列表中元素的个数: length = len(列表名)

查询指定元素出现的次数: count = 列表名.count(元素)
        注意: 查找的元素如果不存在就返回0
        
查询指定元素的索引位置: index = 列表名.index(元素)
        注意:如果查找的元素不存在就报错:ValueError: 元素名 is not in list
        

练习:
# 已知列表存储了10,20,30,40,50按照以下需求分别做下查询操作
# 需求1: 定义列表存储10,20,30,40,50
num_list = [10, 20, 30, 40, 50]

# 需求2: 查询列表中元素的个数
print(len(num_list))

# 需求3: 查询10这个元素出现了几次
print(num_list.count(10))

# 需求4: 查询30这个元素的索引位置
print(num_list.index(30))

其他操作

把列表中元素升序排序: 列表名.sort()

把列表中元素反转存储: 列表名.reverse()

复制列表元素到新列表:  新列表名 = 列表名.copy()


练习:
# 已知列表存储了10,20,30,40,50按照以下需求分别做下查询操作
# 需求1: 定义列表存储10,20,30,40,50
num_list = [10, 20, 30, 40, 50]

# 需求2: 把列表中元素进行升序排序
num_list.sort()

# 需求3: 把列表中元素反转(如果先sort升序,反转类似于倒序)
num_list.reverse()

# 需求4: 复制列表到新的列表中
new_list = num_list.copy()

列表的特点

容器特点:可以容纳多个元素
是否可以混装: 可以容纳不同类型的元素(混装)
是否有下标索引: 数据是有序存储的(有下标序号)
是否支持for循环: 支持
是否支持while循环: 支持
是否允许重复数据: 允许重复数据存在
是否支持元素修改操作: 支持修改

列表的遍历

# 定义列表存储数据
num_list = [10, 20, 30, 40]
# for 循环遍历
for num in num_list:
    print(num)
    
# while 循环遍历
# 初始变量
index = 0 
# while 循环条件
while index < len(num_list):
    # 循环体
    print(num_list[index])
    # 条件控制
    index += 1

元组_tuple

==元组是不可变类型==

元组的定义

定义空元组:
方式1(常用): 元组名 = ()
方式2: 元组名 = tuple()

定义非空元组:
        方式1(常用): 元组名 = (元素1 , 元素2 , 元素3 , ...)
        方式2: 元组名 = ( (元素1,元素2) , (元素1,元素2) , ...)

注意:如果元组中只有一个元素需要加逗号
        定义1个元素的元组:  元组名 = (元素 ,)

元组的下标索引

下标索引: 本质就是每个元素对应的编号, 但是需要注意的是有两套索引

正索引: 从前到后, 从0开始, 依次递增

负索引: 从后到前, 从-1开始, 依次递减

根据索引找元素: 元组名[索引]

元组中最大索引: len(元组)-1

注意:如果访问了不存在的索引就会报错:索引越界异常(IndexError: tuple index out of range)

元组的查询操作

根据索引查询指定位置上的元素: 元组名[索引]

查询元组中元素的总个数: length = len(元组名)

查询指定元素出现的次数: count = 元组名.count(元素)
    注意:查找的元素如果不存在就返回0
    
查询指定元素的索引位置: index = 元组名.index(元素)
    注意:如果查找的元素不存在就报错: ValueError: 元素 is not in tuple

元组的特点

容器特点: 可以存储多个元素
是否可以混装: 可以容纳不同类型的元素(混装)
是否有下标索引: 数据是有序存储的(有下标序号)
是否支持for循环:支持
是否支持while循环:支持
是否允许重复数据: 允许重复数据存在
是否支持元素修改操作: 不支持修改!!!

元组的遍历

name_tuple = ('张三', '李四', '王五')
# for 循环遍历
for name in name_tuple:
    print(name)
    
# while 循环遍历
# 初始变量
index = 0
# while条件
while index < len(name_tuple):
    # 循环体
    print(name_tuple[index])
    # 条件控制
    index += 1

字符串

==字符串是不可变类型==

字符串的定义

知识点:

定义空字符串: 空字符串名 = ''
            空字符串名= ""
定义非空字符串: 字符串名 = '多个字符'
                字符串名 = "多个字符"
                字符串名 = """多个字符_支持换行操作"""

示例:

# 字符串定义
# 字符串定义
# 定义空字符串
s1 = ''
s2 = ""

# 定义非空字符串
s3 = """多个
字符
串
"""

字符串的下标索引

知识点:

下标索引: 本质就是每个元素对应的编号,但是需要注意的是有两套索引

正索引: 从前到后, 从0开始, 依次递增

负索引: 从后到前, 从-1开始, 依次递减

根据索引找元素: 字符串名[索引]

列表中最大索引: len(字符串名) - 1

注意: 如果访问了不存在的索引就会报: 索引越界异常(IndexError: string index out of range

示例:

# 需求1: 定义一个字符串,存储'床前明月光,疑是地上霜'
big_str = '窗前明月光,疑是地上霜'

# 需求2: 查找并打印出第一个元素
# 方式1:正索引(建议)
print(big_str[0])
# 方式2: 负索引
print(big_str[-11])

# 需求3: 查找并打印出第最后一个元素
# 方式1:正索引
prinr(big_str[10])
# 方式2: 负索引(建议)
print(big_str[-1])

# 注意: 如果访问了不存在的索引就会报错
print(big_str[11])

字符串的查询操作

注意: 字符串中的每个元素都是单独小字符串

根据索引查询指定位置上的元素: 字符串名[索引]

查询列表中元素的总个数: length = len(字符串名)

查询指定元素的次数: count = 字符串名.count(元素)
注意:如果查找的元素不存在就报错:ValueError:substring not foung

练习:
# 定义一个字符串,存储'床前明月光,疑是地上霜'
big_str = '窗前明月光,疑是地上霜'

# 根据索引查询指定位置上的元素:  字符串名[索引]
# 需求: 查询第三个字符
print(big_str[2])

# 查询字符串中元素的总个数: length = len(字符串名)
# 需求: 查询字符串有多个字符
print(len(big_str))

# 查询指定元素出现的次数: count = 字符串名.count(元素)
# 需求: 查询月字的出现的次数
print (big_str.count(月))

# 注意: 查找的元素如果不存在就返回0

# 查询指定元素的索引位置: index = 字符串名.index(元素)
# 需求: 查询月字的出现的索引位置
print(big_str.index(月))

# 注意: 如果查找的元素不存在就报错: ValueError: substring not found
# print(big_str.index('汉'))

字符串的特有操作

==本质: 不是修改了原有字符串, 而是重新生成了一个新字符串或者其他类型内容==

基本方法

把原有字符串中指定内容替换成新内容: 新的字符串 = 原有字符串.replace()

把原有字符串中两端空白或指定内容去除: 新的字符串 = 原有字符串.strip()

根据指定分割符,把原有字符串切割成多个字串放到列表中: 列表存储切割的小字符 = 原有字符串.split(分隔符)

练习:
# 需求1: 把"...你TMD哦!!!..."文章字符串中'TMD'替换成'***'
str1 = "...你TMD哦!!!.."
str2 = str1.replace("TMD", "***")
print(str2)
# 需求2: 把" 123456 "密码字符串中两端空白去除:
str3 = "   123456   "

# 默认去重空白
str4 = str3.strip()
print(str4)
# 也可以手动自定空格字符' '去除空白
str5 = str3.strip(' ')
print(str5)
# 需求3: 把"apple-orange-pear-banana"水果切分开自动放到列表中
str6 = "apple-orange-pear-banana"
str7 = str6.split('-')
print(str7)

拓展常用方法

判断是否以某子串开头: 布尔结果 = 字符串名.startswith(子串)
判断是否以某子串结尾: 布尔结果 = 字符串名.endswith(子串)

注意: 以后在字符串中查找索引建议用find,不用index, 因为find返回-1, index报错

从左往右找,返回第一个正索引: 索引 = 字符串.find(子串)
从右往左找,返回第一个正索引: 索引 = 字符串.rfind(子串)

把字符串中所有字母变成大写: 新字符串 = 字符串名.upper()
把字符串中所有字母变成小写: 新字符串 = 字符串名.lower()

注意: 如果不存在就返回-1

字符串的特点

容器特点: 可以容纳多个元素
是否可以混装: 只能存储字符串
是否有下标做因: 数据是有序存储的(有下标序号)
是否支持for循环: 支持
是否支持while循环: 支持
是否允许重复数据: 允许重复数据存在
是否支持元素修改操作: 不支持修改!!

字符串的遍历

# 已知字符串"abcde"
s1 = 'abcde'
# for循环遍历字符串
for i in s1:
    print(i)

print('--------------------')

# while循环遍历字符串
# 1.定义初始变量
index = 0
# 2.条件判断
while index < len(s1):
    # 3.循环体
    print(s1[index])
    # 4.条件控制
    index += 1

序列

==序列: 内容连续,有序,支持下标索引的一类数据容器==

知识点:

常见的序列: 列表,元组,字符串

序列切片格式: 序列[起始索引:结束索引:步长]
            起始索引:可以省略,省略就代表从头开始
            结束索引:可以省略,省略就代表一直到末尾结束
            步长:可以省略,省略就代表步长为1(可以为负数,表示倒序执行)

集合

==集合(set)是可变类型

集合的定义

定义空集合: 集合名 = set()  注意: {}代表空字典

定义非空集合: 集合名 = {元素1, 元素2,...}

集合的增删改查操作

增加/删除

增加: 集合名.add(要添加的元素)

删除: 集合名.remove(要删除的元素)  # 移除指定元素
     集合名.pop(元素名)  # 随机删除一个元素
     集合名.clear()  # 清空集合

修改/查询

# 定义集合
set1 = {10, 20, 30}
set2 = {10, 60, 70}
print('原始set1内容:',set1)
print('原始set2内容:',set2)
# 更新set1集合内容为set1和set2的差集
# 相当于把difference差集结果覆盖了原来set1的内容
set1.difference_update(set2)
print(set1)
print(set2)

# 更新set1集合内容为set1和set2的并集
# 相当于把union合并后的结果覆盖了原来set1的内容
set1.update(set2)
print(set1)
print(set2)


# 查询set1最终的结果长度
print(len(set1))

集合的特点

容器特点: 可以容纳多个元素
是否可以混装: 可以容纳不同类型的元素(混装)
是否有下标索引:  没有
是否支持for循环: 支持(因为for循环又叫遍历循环)
是否支持while循环: 不支持(因为没有下标序号)
是否允许重复数据: 不允许重复(因为默认有去重功能)
是否支持元素修改操作: 支持修改(增加或删除元素等)

集合的遍历

# 定义容器要求不能有重复元素
name_set = {'张三', '李四', '李四', '张三', '赵六', '王五'}
print(name_set)
# 遍历集合
for name in name_set:
    # 直接打印元素
    print(name)
"""
曲线救国方式使用while
注意集合不能使用while遍历,因为集合没有下标索引
但是列表,元组等有下标索引,可以转换为列表再用while遍历
"""
name_list = list(name_set)
print(name_list)

# 接下来就可以使用列表的while遍历
# 初始变量
index = 0
# 条件判断
while index < len(name_list):
    # 循环体
    name = name_list[index]
    print(name)
    # 条件控制
    index += 1

字典

=字典(dict)是可变类型

字典的定义

知识点

定义空字典: 字典名 = {}

定义非空字典: 字典名 = {key1:value1, key2:value2,...}

示例:

# 1.定义空字典
dict1 = {}
print(dict1,type(dict1))
dict2 = dict()
print(dict2)

# 2. 定义非空字典
stu_dict = {'张三':99, '李四': 100, '王五': 89}
print(stu_dict)

字典的键值对

知识点:

字典的键: key 字典中的 key 可以是不可变类型数据
字典的值: value 字典中的value 可以是任意类型

根据key获取到对应的值: value = 字典名[key]

注意1: key 不能重复,如果重复了后面的值会替换前面的值, 但是value值可以重复
注意2: 如果访问的key不存在,就报错 KeyError: key

示例

# 需求1: 已知以下字典,存储姓名和年龄
# 注意: key不能重复,如果重复了后面的值会替换前面的值
stu_dict1 = {'张三': 18, '王五': 19, '张三': 19}
print(stu_dict1)
# 找出李四的年龄
age = stu_dict1['张三']
print(f'"张三"的年龄是:{age}')
# 注意: 如果访问的key不存在,就报错 KeyError: key
# print(stu_dict1['李四'])

# 需求2: 定义字典,存储学生姓名以及对应的各科成绩
stu_dict2 = {
    '张三': {'语文': 100, '数学': 99, '外语': 60},
    '李四': {'语文': 99, '数学': 98, '外语': 61},
    '王五': {'语文': 100, '数学': 97, '外语': 62}
}
# print(stu_dict2)

# 需求3: 找出王五的各科成绩
print('王五的各科成绩:', stu_dict2['王五'])

# 需求4: 找出李四的数学成绩
print('李四的数学成绩:', stu_dict2['李四']['数学'])

字典的增删改查操作

增加/修改操作

知识点:

增加键值对: 字典名[新的key] = 新值

修改键值对: 字典名[旧的key] = 新值

注意: 增加和修改格式是一模一样的, 主要取决于key是否存在

示例:

# 需求1: 定义空字典
stu_dict = {}
print(stu_dict) # {}
# 需求2: 往空字典中添加键值对 张三:18
stu_dict['张三'] = 18
print(stu_dict) # {'张三': 18}

# 注意: 添加新键值对,key一定不能是已存在的,否则就变成了修改
stu_dict['张三'] = 19
print(stu_dict) # {'张三': 19}

# 注意: 修改键值对,key一定要写对,否则就变成了新增!!!
stu_dict['张三 '] = 28
print(stu_dict)  # {'张三': 19, '张三 ': 28}

查询/删除操作

知识点:

获取字典中键值对个数:  len(字典名)
获取字典中所有的key:  字典名.keys()
获取字典中所有的value: 字典名.values()
获取字典中所有的键值对: 字典名.items()
根据键key获取值value:  方式1: value=字典名[key]        方式2: value=字典名.get(key)

根据键key删除整个键值对: 方式1: 字典名.pop(key)          方式2: del 字典名[key]
注意: 返回值的是被删除的对应的值,一般不用
清空字典中所有的键值对:  字典名.clear()

示例:

# 需求1: 定义非空字典存储一个学生信息
stu_dict = {'姓名': '张三', '年龄': 18, '身高': 178.8, '体重': 66.6}
print(stu_dict)
# 需求2: 查找字典中有几种学生信息(几个键值对)
print(len(stu_dict))
# 需求3: 查找字典中有哪几类的学生信息(获取所有的key)
print(stu_dict.keys())
# 需求4: 打印出学生的具体信息(获取所有的值)
print(stu_dict.values())
# 需求5: 查找所有的键值对
print(stu_dict.items())
# 需求6: 查找字典中学生的姓名是什么
print(stu_dict['姓名'])
print(stu_dict.get('姓名'))

# 需求7: 使用pop删除体重信息
stu_dict.pop('体重')
print(stu_dict)
# 需求8: 使用del 字典名[key]删除身高信息
del stu_dict['身高']
print(stu_dict)
# 需求9: 清空所有信息
stu_dict.clear()
print(stu_dict)

字典的特点

容器特点: 可以容纳多个元素(每个元素是一个键值对)
是否可以混装: 可以容纳不同类型的元素(key不能是字典类型)
是否有下标索引:  不支持下标索引
是否支持for循环: 支持(因为for循环又叫遍历循环)
是否支持while循环: 不支持(因为没有下标索引)
是否允许重复数据:  key不能重复(如果重复就会覆盖),但是value可以重复
是否支持元素修改操作: 支持修改(增加或删除元素等)

字典的遍历

# 定义字典存储学生信息
stu_dict = {'姓名': '张三', '年龄': 18, '身高': 178.8, '体重': 66.6}
print(stu_dict)

# 需求1: 遍历字典打印所有的key
#  方式1 注意: 直接遍历字典,得到的值是key
for key in stu_dict:
    print(key)
print('------------------------------')
#  方式2 通过keys也能遍历所有的key
for key in stu_dict.keys():
    print(key)

print('------------------------------')

# 需求2: 遍历字典打印所有的值
for value in stu_dict.values():
    print(value)

print('------------------------------')

# 需求3: 遍历字典打印分别所有的键值对
for item in stu_dict.items():
    print(item)