目录

第一部分:容器入门

1、什么是容器

2、容器的分类

第二部分:五大容器详解

1. 字符串容器(一个字符串可以存放任意数量的字符)

1.1 字符串的定义

1.2 字符串的下标索引

1.3 字符串的查询操作

1.4 字符串的切片操作

1.5 字符串的特有操作!!

1.6 字符串的遍历

2. 列表容器

2.1 列表的定义

2.2 列表的下标索引

2.3 列表的增删改查(重点)

2.4 列表的遍历

2.5 列表的特点总结

3. 元组容器(元组同列表一样,都是可以封装多个、不同类型的元素在内)

3.1 元组的定义

3.2 元组的下标索引

3.3 元组的查询操作

3.4 元组的遍历

3.5 元组相关操作的注意事项

3.6 元组的特点总结

4. 集合容器

4.1 集合的定义

4.2 集合的增删改查

4.3 集合的遍历

4.4 集合的特点总结

5. 字典容器

5.1 字典的定义

5.2 字典的键值访问

5.3 字典的增删改查

5.4 字典的遍历(注意:字典不支持下标索引,所以同样不可以用while循环遍历)

5.5  集合的特点总结

第三部分、序列详解

第四部分:推导式详解

1、什么是推导式

2、支持推导式的容器

3、列表推导式

基础语法

[表达式 for 变量 in 可迭代对象]

[表达式 for 变量 in 可迭代对象 if 条件]

示例

4、集合推导式

基础语法

{表达式 for 变量 in 可迭代对象}

{表达式 for 变量 in 可迭代对象 if 条件}

示例

5、字典推导式

基础语法

{键表达式: 值表达式 for 变量 in 可迭代对象}

{键表达式: 值表达式 for 变量 in 可迭代对象 if 条件}

示例

6、生成器推导式

第五部分:五大容器总结对比

1、分类

2、通用操作

示例代码

3、容器转换

前言

在Python中,我们经常需要处理一些数据。比如一个班级的所有学生姓名、一家店铺的所有商品价格、一本词典的单词释义……这些场景都需要一种能够容纳多个元素的数据类型,这就是容器。

Python提供了五大核心容器:字符串(str)、列表(list)、元组(tuple)、集合(set)、字典(dict),每种容器都有其独特的特性和适用场景。本文将全面深入地讲解这五大容器,这也是python学习中极为重要的部分。

第一部分:容器入门

1、什么是容器

容器概念:一种可以容纳多份数据的Python数据类型,容纳的每一份数据称之为1个元素 每一个元素,可以是任意类型的数据,如字符串、数字、布尔等。简单来说,容器就像是收纳盒,可以把多个数据整齐地存放在一起,方便统一管理。

2、容器的分类

Python中的五大容器:字符串(str)、列表(list)、元组(tuple)、集合(set)、字典(dict)。

第二部分:五大容器详解

知识点

1. 字符串容器(一个字符串可以存放任意数量的字符)

核心要点:字符串是不可变类型,所有修改操作都会返回新字符串(需要定义新变量来接收)

1.1 字符串的定义

定义空字符串: ' '  ," "  , '''  '''  , """  """  ,str()
 
定义非空字符串: '字符内容' ,"字符内容"  ,'''字符内容'''  ,"""字符内容"""

注意: 引号可以嵌套包裹

示例

python
#  定义空字符串
s1 = ''
s2 = ""
s3 = ''''''
s4 = """"""
s5 = str()
print(s1, s2, s3, s4, s5)
print(type(s1), type(s2), type(s3), type(s4), type(s5))
# 输出:   
# <class 'str'> <class 'str'> <class 'str'> <class 'str'> <class 'str'>


# 定义非空字符串 
s6 = 'abcd'
s7 = "abcd"
s8 = '''ab
cd'''      # 三引号支持换行
s9 = """ab
cd"""      # 三引号支持换行
print(s6, type(s6))   # abcd <class 'str'>
print(s7, type(s7))   # abcd <class 'str'>
print(s8, type(s8))   # ab\ncd <class 'str'>
print(s9, type(s9))   # ab\ncd <class 'str'>

# 字符串引号嵌套 
s10 = "我最近看了一本书,书名是'钢铁是怎样练成的'!"
print(s10, type(s10))
# 输出:我最近看了一本书,书名是'钢铁是怎样练成的'! <class 'str'>

1.2 字符串的下标索引

知识点

索引: 也叫下标,就是常说的编号,只是这个编号比较特殊,有两套编号。

正索引:从左到右,从0开始依次递增
负索引:从右到左,从-1开始依次递减

字符串名[索引]: 查询指定索引位置处的元素,不能越界访问

示例:

python
# 定义非空字符串
ss = "abcdefg"

# 获取第一个位置的字符
print(ss[0])    # a
print(ss[-7])   # a

# 获取第四个位置的字符
print(ss[3])    # d
print(ss[-4])   # d

# 获取最后一个位置的字符
print(ss[-1])   # g
print(ss[6])    # g

# 注意:访问不存在的索引会报索引越界异常
# print(ss[7])  # IndexError: string index out of range

1.3 字符串的查询操作

知识点

    字符串名[索引]: 查询指定索引位置处的元素
    字符串名.count(元素):查询指定元素在字符串中出现的次数    

    注意:如果元素不存在就返回0
    字符串名.index(元素):查询指定元素在字符串中出现的索引位置 

    注意:如果元素有多个只返回第一个,如果不存在就报错
    len(字符串名): 查询指定字符串的元素总个数

示例

python
# 定义非空字符串
ss = 'abcdeaaabb'

# 1.字符串名[索引]: 查询指定索引位置处的元素
# 需求: 查找第一个位置元素是什么
print(ss[0])           # a
# 需求: 查找最后一个位置元素是什么
print(ss[-1])           # b

# 2.len(字符串名): 查询指定字符串的元素总个数
print(len(ss))         # 10

# 3.字符串名.count(元素):查询指定元素在字符串中出现的次数
# 需求: 查找'a'元素的个数
print(ss.count('a'))   # 4(a出现了4次)
# 需求: 查找'z'元素的个数
print(ss.count('z'))   # 0(不存在返回0)

# 3.字符串名.index(元素):查询指定元素在字符串中出现的索引位置 
# 注意:如果元素多个只返回第一个
print(ss.index('a'))   # 0(返回第一个a的索引)
# 如果不存在就报错
print(ss.index('z')) # 报错!ValueError

# 删除整个字符串
del ss
# print(ss)  # 报错!NameError: name 'ss' is not defined


#注意:字符串不支持修改操作(元素的增删改)
# ss.append('f')  # 报错
# del ss[0]       # 报错
# ss[0] = 'f'     # 报错

注意:字符串不支持修改

1.4 字符串的切片操作

切片的前提:是容器,要有索引!
切片的格式:字符串名[起始索引:结束标记(不含):步长]
切片的特点:包左不包右,起始索引如果不写默认从头开始,结束标记不写默认到末尾,步长默认是1
切片的方向:步长如果是正数0就是头,步长如果是负数-1就是头
例:
字符串: abcdefg
正索引: 0 1 2 3 4 5 6
负索引:-7-6-5-4-3-2-1

示例

# 定义字符串变量存储'itheima'
s = 'itheima'
# 需求: 打印字符串
print(s)    #itheima
print(s[::1])    #itheima
print(s[::])     #itheima
print(s[:])      #itheima

# 需求: 要求反转字符串打印
print(s[::-1])    #amiehti

# 需求: 截取出it
print(s[0:2])
print(s[-7:-5])
print(s[-7:2])
print(s[:2])

# 需求: 截取出hei
print(s[2:5:])
print(s[-5:-2:])
print(s[-5:5:])

# 需求: 截取出ma
print(s[5:7:])
print(s[5::])
print(s[-2::])

# 需求: 截取出ihia
print(s[::2])

1.5 字符串的特有操作!!

知识点

replace(旧字符串,新字符串,替换几次): 把指定旧字符串替换为新字符串,默认替换所有
strip(): 默认就是去除两端的空白

split(分隔符,切几次): 根据指定分隔符切割字符串,默认切所有并放到列表中
分隔符.join(存储了字符串的容器): 用指定分隔符把容器中的字符串拼接一个大字符串

startswith(字符串): 判断是否以指定字符串开头
endswith(字符串): 判断是否以指定字符串结尾

encode(编码): 编码操作
decode(编码): 解码操作

upper(): 把所有字母都转为大写
lower(): 把所有字母都转为小写

find(元素):从左往右查找指定元素在字符串中出现的索引位置(正索引),如果不存在就返回-1

注意:find用法和index几乎一致,都是查找指定元素的索引,唯一不同的是找不到find返回-1,index则报错(count找不到会返回0)。
rfind(元素):从右往左查找指定元素在字符串中出现的索引位置(正索引),如果不存在就返回-1

isdigit(): 判断字符串内容是否是数字
注意:字符串是不可变类型,这些操作并不会修改原字符串,而是返回一个新的字符串!

示例

python
# 1. replace(旧字符串, 新字符串, 替换次数):把指定旧字符串替换为新字符串,默认替换所有
s1 = '你TMD哦,真的TMD哦!'
new_s1 = s1.replace('TMD', '***')
print(s1)        # 你TMD哦,真的TMD哦!
print(new_s1)    # 你***哦,真的***哦!

# 指定替换次数
new_s1_limited = s1.replace('TMD', '***', 1)
print(new_s1_limited)  # 你***哦,真的TMD哦!

# 2. strip():去除两端空白
s2 = '    张三 18    '
new_s2 = s2.strip()
print(s2)        # '    张三 18    '
print(new_s2)    # '张三 18'

# 3. split(分隔符,切几次):根据指定分隔符切割字符串,默认切所有并放到列表中
s3 = "苹果,香蕉,橘子,火龙果,榴莲"
new_s3 = s3.split(',')
print(s3)        # 苹果,香蕉,橘子,火龙果,榴莲
print(new_s3)    # ['苹果', '香蕉', '橘子', '火龙果', '榴莲']

# 4. join(存储了字符串的容器):用指定分隔符把容器中的字符串拼接一个大字符串
s4 = ['苹果', '香蕉', '橘子', '火龙果', '榴莲']
new_s4 = '-'.join(s4)
print(s4)        # ['苹果', '香蕉', '橘子', '火龙果', '榴莲']
print(new_s4)    # 苹果-香蕉-橘子-火龙果-榴莲

# 5. startswith(字符串): 判断是否以指定字符串开头
print('张三丰'.startswith('张'))    #True
print('张三丰'.startswith('王'))    #False
# 6.endswith(字符串): 判断是否以指定字符串结尾
print('张三丰'.endswith('丰'))    #True
print('张三丰'.endswith('锋'))    #False

# 7.encode(编码): 编码操作
print('你好'.encode('utf8'))
# 8.decode(编码): 解码操作
print(b'\xe4\xbd\xa0\xe5\xa5\xbd'.decode('gbk'))
print(b'\xe4\xbd\xa0\xe5\xa5\xbd'.decode('utf8'))

# 9. upper():把所有字母都转为大写 
#    lower():把所有字母都转为小写
print('ABCabc'.upper())  # ABCABC
print('ABCabc'.lower())  # abcabc

# 10. isdigit()判断字符串内容是否是数字(整数)
print('abc'.isdigit())   # False
print('10'.isdigit())    # True

# 11.find(元素):从左往右查找指定元素在字符串中出现的索引位置(正索引)
print('ihema'.find('i'))    # 0
# 如果不存在就返回-1
print('ihema'.find('b'))

# 12.rfind(元素):从右往左查找指定元素在字符串中出现的索引位置(正索引),如果不存在就返回-1
print('iyyhimal'.rfind('i'))    # 4
# 如果不存在就返回-1
print('iyyhimal'.rfind('b'))

# 13.find() vs index()
ss = 'abcdeaaabb'
print(ss.find('a'))   # 0(找到返回索引)
print(ss.find('f'))   # -1(找不到返回-1)

# index()找不到会报错
print(ss.index('a'))  # 0
# print(ss.index('f'))  # ValueError!

1.6 字符串的遍历

方式1:for循环

for循环又叫遍历循环,格式如下:

for 元素变量 in 字符串:
    循环体

方式2:while循环

while循环,用变量充当索引使用,格式如下:

index = 0
while index < len(字符串):
    元素变量 = 字符串[index]
    循环体
    index += 1

示例:

python
# 定义非空字符串
ss = 'abcde'
# for循环方式
for s in ss:
    print(s,end='')    #abcde

# while循环方式
index = 0
while index < len(ss):
    s = ss[index]
    print(s,end='')
    index += 1        #abcde

不同与列表和元组的在于:字符串容器可以容纳的类型是单一的,只能是字符串类型。

不同于列表,相同于元组的在于:字符串不可修改

1.7 字符串的特点总结
1.可以容纳多个元素
2.元素只能是字符!
3.元素可以重复
4.元素不可以修改!
5.元素是有序的
6.元素是有下标索引
7.支持for循环遍历
8.支持while循环遍历

2. 列表容器

核心要点:列表是可变类型,是Python中最常用的容器

注意:列表可以一次存储多个数据,且可以为不同的数据类型,支持嵌套

2.1 列表的定义

定义空列表:  []  或者 list()

定义非空列表: [元素1,元素2,元素3, ...]

列表支持嵌套: [ [元素...] , [元素...] ]

示例:

python
# 定义空列表
l1 = []
print(l1, type(l1))   # [] <class 'list'>

l2 = list()
print(l2, type(l2))   # [] <class 'list'>

# 定义非空列表(可以存储任意类型)
l3 = ['张三', '李四', 10, 20, 3.14, 13.14, True, False]
print(l3, type(l3))    #['张三', '李四', 10, 20, 3.14, 13.14, True, False] <class 'list'>

# 列表嵌套
l4 = [l1, l2, l3]
print(l4, type(l4))

2.2 列表的下标索引

知识点

索引: 也叫下标,就是编号,只是这个编号比较特殊,有两套编号

正索引:从左到右,从0开始依次递增
负索引:从右到左,从-1开始依次递减

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

示例:

python
# 定义非空列表分别存储姓名和年龄
name_list = ['张三', '李四', '王五']
age_list = [18, 28, 38]

# 分别获取第一个姓名和第一个年龄
print(name_list[0])   # 张三
print(age_list[0])    # 18

# 分别获取最后一个姓名和最后一个年龄
print(name_list[-1])  # 王五
print(age_list[-1])   # 38

# 列表嵌套(定义学生信息列表把姓名和年龄列表再次封装起来)
stu_list = [name_list, age_list]

# 获取第一个姓名和第一个年龄
print(stu_list[0][0])  # 张三
print(stu_list[1][0])  # 18

# 获取最后一个姓名和最后一个年龄
print(stu_list[0][-1])  # 王五
print(stu_list[1][-1])  # 38

2.3 列表的增删改查(重点

知识点

增:
    列表名.append(元素): 把指定元素追加到对应列表中——重点
    列表名.extend(容器): 把指定容器中的元素依次取出追加到对应列表中
    列表名.insert(索引,元素): 把指定元素插入到对应列表的指定索引位置

拓展:在列表中,append()只能在尾部插入一个元素,extend()可以在尾部一次插入多个元素。

删:
    列表名.pop(索引): 把指定索引位置处元素从列表中删除——重点  
    del 列表名[索引]: 把指定索引位置处元素从列表中删除
    列表名.remove(元素): 把指定元素直接从列表中删除   注意:一次只会删除一个 ——重点
    列表名.clear(): 清空列表中所有元素
    del 列表名: 删除整个列表
改:
    列表名[索引] = 新元素 : 修改列表指定索引位置的元素——重点
查:
    列表名[索引]: 查询指定索引位置处的元素 ——重点      
    列表名.count(元素):查询指定元素在列表中出现的次数    注意:如果元素不存在就返回0——重点
    列表名.index(元素):查询指定元素在列表中出现的索引位置 注意:如果元素不存在就报错,多个只返回第一个位置
    len(列表名): 查询指定列表的元素总个数——重点

示例:

python
"""列表是可变类型"""

# 0. 定义空列表
names = []
print(names)  # []

# 1.增
# 列表名.append(元素): 把指定元素追加到对应列表中
names.append('张三')
print(names)  # ['张三']

# 列表名.extend(容器): 把指定容器中的元素依次取出追加到对应列表中
names.extend(['张三', '李四', '王五'])
print(names)  # ['张三', '张三', '李四', '王五']

# 列表名.insert(索引,元素): 把指定元素插入到对应列表的指定索引位置
names.insert(0, '熊大')
print(names)  # ['熊大', '张三', '张三', '李四', '王五']

names.insert(1, '熊二')
print(names)  # ['熊大', '熊二', '张三', '张三', '李四', '王五']

print(names.insert(0, '熊大'))  #None   insert没有返回值,不能这样写

# 2.改
# 列表名[索引] = 新元素 : 修改列表指定索引位置的元素
names[0] = 'ss'
print(names)  # ['ss', '熊二', '张三', '张三', '李四', '王五']

# 3.查
# 列表名[索引]: 查询指定索引位置处的元素
print(names[0])  # ss

# 列表名.count(元素):查询指定元素在列表中出现的次数    
# 注意:如果元素不存在就返回0
print(names.count('张三'))  # 2

# 列表名.index(元素):查询指定元素在列表中出现的索引位置 
# 注意:如果元素不存在就报错,多个只返回第一个位置
print(names.index('张三'))  # 2(返回第一个匹配的索引)
print(names.index('张丰'))  # 报错!

# len(列表名): 查询指定列表的元素总个数
print(len(names))  # 6

# 4.删
# 列表名.pop(索引): 把指定索引位置处元素从列表中删除
names.pop(0)
print(names)  # ['熊二', '张三', '张三', '李四', '王五']

# del 列表名[索引]: 把指定索引位置处元素从列表中删除
del names[0]
print(names)  # ['张三', '张三', '李四', '王五']

# 列表名.remove(元素): 把指定元素直接从列表中删除   
# 注意:一次只会删除一个
names.remove('张三')
print(names)  # ['张三', '李四', '王五']

names.remove('张三')
print(names)  # ['李四', '王五']

# 列表名.clear(): 清空列表中所有元素
names.clear()
print(names)  # []

# del 列表名: 删除整个列表
del names
print(names)  # NameError: name 'names' is not defined

列表的方法 - 总览

编号

使用方式

作用

1

列表.append(元素)

向列表中追加一个元素

2

列表.extend(容器)

将数据容器的内容依次取出,追加到列表尾部

3

列表.insert(下标元素)

在指定下标处,插入指定的元素

4

del 列表[下标]

删除列表指定下标元素

5

列表.pop(下标)

除列表指定下标元素

6

列表.remove(元素)

从前向后,删除此元素第一个匹配项

7

列表.clear()

清空列表

8

列表.count(元素)

统计此元素在列表中出现的次数

9

列表.index(元素)

查找指定元素在列表的下标

找不到报错ValueError

10

len(列表)

统计容器内有多少元素

2.4 列表的遍历

方式1:for循环,又叫遍历循环,格式如下:

for 元素变量 in 列表名:
    循环体

方式2:while循环,用变量充当索引使用,格式如下:

index = 0
while index < len(列表名):
    元素变量 = 列表名[index]
    循环体
    index += 1

示例:

python
# 需求: 定义非空列表,然后遍历打印元素
names = ['熊大', '熊二', '张三', '李四', '王五']
# for循环方式
# 核心思想: 依次从列表中取出每个元素赋值给临时变量
for name in names:
    print(name)

# while循环方式
# 核心思想: 用while循环的变量作为列表的索引使用
index = 0
while index < len(names):
    # 根据索引获取元素  index此时就充当索引使用
    name = names[index]
    print(name)
    # 条件控制
    index += 1

2.5 列表的特点总结


列表的特点:
1. 支持容纳多个元素
2. 支持for循环遍历
3. 支持修改操作(可变类型)
4. 能存储任意类型数据
5. 有下标索引 → 支持while循环
6. 有下标索引 → 有序(存取顺序一致)
7. 有下标索引 → 可以重复

3. 元组容器(元组同列表一样,都是可以封装多个、不同类型的元素在内)

核心要点:元组是不可变类型,一旦创建就不能修改

3.1 元组的定义

定义空元组: () 或者 tuple()

定义非空元组: (元素1,元素2,元素3,...)   

注意!: 如果元组中只有一个元素,必须加逗号     格式:  (元素,)

解释:系统会把括号当成优先级,加上逗号才会被认为是元组。

示例

python
# 定义空元组
t1 = ()
print(t1, type(t1))   # () <class 'tuple'>

t2 = tuple()
print(t2, type(t2))   # () <class 'tuple'>

# 定义非空元组
t3 = ('张三', '李四', 10, 20, 3.14, 13.14, True, False)
print(t3, type(t3))   #('张三', '李四', 10, 20, 3.14, 13.14, True, False) <class 'tuple'>

# 元组嵌套
t4 = (t1, t2, t3)
print(t4, type(t4))  #('张三', '李四', 10, 20, 3.14, 13.14, True, False) <class 'tuple'>

# 注意: 如果是一个元素的元组,一定加逗号!!!
t5 = ('张三',)
print(t5, type(t5))  #('张三',) <class 'tuple'>
t6 = ('张三')         # 这不是元组,是字符串
print(t6, type(t6))   # 张三 <class 'str'>

3.2 元组的下标索引

与列表类似,元组也支持正索引和负索引

正索引:从左到右,从0开始依次递增
负索引:从右到左,从-1开始依次递减

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

python
# 定义非空元组
name_tuple = ('张三', '李四', '王五')
age_tuple = (18, 28, 38)

# 获取第一个元素
print(name_tuple[0])   # 张三
print(age_tuple[0])    # 18

# 获取最后一个元素
print(name_tuple[-1])  # 王五
print(age_tuple[-1])   # 38

# 元组嵌套(定义学生信息元组把姓名和年龄元组再次封装起来)
stu_tuple = (name_tuple, age_tuple)

# 获取第一个姓名和第一个年龄
print(stu_tuple[0][0])  # 张三
print(stu_tuple[1][0])  # 18

# 获取最后一个姓名和最后一个年龄
print(stu_tuple[0][-1])  # 王五
print(stu_tuple[1][-1])  # 38

3.3 元组的查询操作


    元组名[索引]: 查询指定索引位置处的元素
    元组名.count(元素):查询指定元素在元组中出现的次数    注意:如果元素不存在就返回0
    元组名.index(元素):查询指定元素在元组中出现的索引位置 注意:如果元素不存在就报错,多个只返回第一个位置
    len(元组名): 查询指定元组的元素总个数

示例:

python
"""元组是不可变类型"""

# 定义非空元组
names = ('张三', '李四', '王五', '张三')
print(names)

# 元组名[索引]: 查询指定索引位置处的元素
print(names[0])      # 张三

# 元组名.count(元素):查询指定元素在元组中出现的次数    
# 注意:如果元素不存在就返回0
print(names.count('张三'))  # 2
print(names.count('赵六'))  # 0

# 元组名.index(元素):查询指定元素在元组中出现的索引位置 
# 注意:如果元素不存在就报错,多个只返回第一个位置
print(names.index('张三'))  # 0(返回第一个匹配的索引)
print(names.index('赵六'))  # 报错!ValueError

# len():获取长度
print(len(names))    # 4

# 注意:元组不支持修改操作
names[0] = '新名字'  # 报错!TypeError
names.append('新名字')  # 报错!
del names[0]  # 报错!

3.4 元组的遍历

python
# 定义非空元组,然后遍历打印元素
names = ('熊大', '熊二', '张三', '李四', '王五')

# for循环方式
# 核心思想: 依次从元组中取出每个元素赋值给临时变量
for name in names:
    print(name)

# while循环方式
# 核心思想: 用while循环的变量作为元组的索引使用
index = 0
while index < len(names):
    # 根据索引获取元素  index此时就充当索引使用
    name = names[index]
    print(name)
    # 条件控制
    index += 1

3.5 元组相关操作的注意事项

1.不可以修改元组的内容,否则会直接报错

#尝试修改元组内容
t1=[1,2,3]
ti[0]=5    #报错

2.可以修改元组内的list的内容(修改元素、增加、删除、反转等)
 

#尝试修改元组内容
t1=(1,,2,['abc','sss'])
t1[2][1]='best'
print(t1)    #(1,,2,['abc','best'])

3.不可以替换list为其它list或其它类型

#尝试修改元组内容
t1=(1,,2,['abc','sss'])
t1[2]='[1,2,3]
print(t1)    #报错

3.6 元组的特点总结


1. 支持容纳多个元素
2. 支持for循环遍历
3. 不支持修改操作(不可变类型)
4. 能存储任意类型数据
5. 有下标索引 → 支持while循环
6. 有下标索引 → 有序
7. 有下标索引 → 可以重复

4. 集合容器

核心要点:集合是可变类型,具有无序不重复的特性

4.1 集合的定义

定义空集合:  集合名 = set()

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

集合核心特点: 无序不重复   元素只能是不可变类型(整数,浮点数,布尔值,字符串,元组)

可以这样理解:集合中有重复元素时,一开始就会去重,如果存储了可变类型元素,虽然一开始并没有重复,但由于可变,对元素更改后可能会与之前集合内元素重复,违背了集合一开始就去重的原则,所以集合内不能存储可变类型数据。

 注意:{} 是空字典,不是空集合!

示例

python
# 定义空集合
# 注意:空的{}代表是字典,不是集合!
d1 = {}
print(d1, type(d1))  # {} <class 'dict'>

s1 = set()
print(s1, type(s1))  # set() <class 'set'>

# 定义非空集合
# 注意1:集合自带去重功能
s2 = {'张三', '李四', 10, 10, 3.14, 3.14, True, False}
print(s2, type(s2))  
# 输出:{False, True, 10, 3.14, '李四', '张三'}(顺序可能不同)

# 注意2:集合中只能放不可变类型
# 可变类型(列表、集合、字典)不能放入集合
s3 = {10, 3.14, True, "123", ('a', 'b')}  # 元组可以
print(s3, type(s3))

# 以下会报错
# s4 = {10, [1, 2]}  # TypeError: unhashable type: 'list'

4.2 集合的增删改查

增:
    集合名.add(元素): 把指定元素添加到对应集合中

    注意:集合的添加只有add(),没有append,extend等操作
删:
    集合名.pop(): 随机删除一个元素
    集合名.remove(元素): 把指定元素直接从集合中删除   注意:一次只会删除一个
    集合名.clear(): 清空集合中所有元素
    del 集合名: 删除整个集合
改:
    集合1.difference_update(集合2): 修改集合1的内容为它和集合2元素的差集
    集合1.update(集合2): 修改集合1的内容为它和集合2的并集
查:
    len(集合名): 查询集合元素的总个数

示例:

python
"""集合是可变类型"""

# 0. 定义空集合
names = set()
print(names)  # set()


# 1.增
# 集合名.add(元素): 把指定元素追加到对应集合中
names.add('张三')
names.add('李四')
names.add('王五')
print(names)  # {'张三', '李四', '王五'}

# 2.改
# difference_update(集合2):修改为差集
names.difference_update({'张三', '赵六'})
print(names)  # {'李四', '王五'}

# update(集合2):修改为并集
names.update({'张三', '赵六'})
print(names)  # {'张三', '李四', '王五', '赵六'}

# 3.查
# len():获取长度
print(len(names))  # 4

# 4.删
# pop():随机删除一个元素
names.pop()
print(names)

# remove(元素):删除指定元素
names.remove('张三')
print(names)

# clear():清空集合
names.clear()
print(names)  # set()

# del 集合:删除整个集合
del names
# print(names)  # NameError

4.3 集合的遍历

只支持for循环,格式如下:

for 元素变量 in 集合名:
    循环体

由于while循环必须用变量充当索引使用,集合没有索引,所以集合不支持while循环。

python
# 定义非空集合,然后遍历打印元素
names = {'ss', '张三', '李四', '王五'}
# for循环方式
# 核心思想: 依次从集合中取出每个元素赋值给临时变量
for name in names:
    print(name)

 注意:集合没有下标索引,不支持while循环!

4.4 集合的特点总结


1. 支持容纳多个元素
2. 支持for循环遍历
3. 支持修改操作(可变类型)
4. 只能存储不可变类型数据(整数、浮点数、布尔值、字符串、元组)
5. 没有下标索引 → 不支持while循环
6. 没有下标索引 → 无序
7. 没有下标索引 → 元素不重复(自动去重)

5. 字典容器

核心要点:字典是可变类型,以键值对形式存储数据

5.1 字典的定义

定义空字典:  字典名 = {}  和  字典名 = dict()

定义非空字典: 字典名 = {k1:v1 , k2:v2 , k3:v3 ...}

注意: 键key只能是不可变类型且不能重复,值value可以是任意类型且可以重复。

示例:

python
# 定义空字典
d1 = {}
print(d1, type(d1))   # {} <class 'dict'>

d2 = dict()
print(d2, type(d2))   # {} <class 'dict'>

# 定义非空字典
d3 = {"张三": 18, "李四": 28, '王五': 38}
print(d3, type(d3))    #{'张三': 18, '李四': 28, '王五': 38} <class 'dict'>

# 字典嵌套
# 注意: key不能重复且不能是可变类型: 列表,集合,字典
# key只能是不可变类型: 整数,浮点数,布尔值,字符串,元组
d4 = {1: d1, 2: d2, 3: d3}
print(d4, type(d4)) 
#{1: {}, 2: {}, 3: {'张三': 18, '李四': 28, '王五': 38}} <class 'dict'>


# 综合案例:存储每个学生的成绩
score_dict = {
    "张三": {'语文': 99, '数学': 88, '英语': 98},
    "李四": {'语文': 89, '数学': 68, '英语': 100},
    "王五": {'语文': 79, '数学': 98, '英语': 99},
}
print(score_dict, type(score_dict))

# 注意:key重复时,后面的值会覆盖前面的值
info_dict = {"张三": 18, "李四": 28, '王五': 38, '张三': 38}
print(info_dict)  # {'张三': 38, '李四': 28, '王五': 38}

5.2 字典的键值访问

字典名[key]:  根据指定的键key获取值value

字典名.get(key):  根据指定的键key获取值value

示例:

python
# 定义非空字典
info_dict = {"张三": 18, "李四": 28, '王五': 38}
print(info_dict)

# 根据键获取值
print(info_dict['张三'])   # 18
print(info_dict['王五'])   # 38

# 字典嵌套访问
score_dict = {
    "张三": {'语文': 99, '数学': 88, '英语': 98},
    "李四": {'语文': 89, '数学': 68, '英语': 100},
    "王五": {'语文': 79, '数学': 98, '英语': 99},
}

# 获取张三的所有成绩
print(score_dict['张三'])  # {'语文': 99, '数学': 88, '英语': 98}

# 获取张三的数学成绩
print(score_dict['张三']['数学'])  # 88

# 获取李四的英语成绩
print(score_dict['李四']['英语'])  # 100

5.3 字典的增删改查

增:
    字典名[新key] = value   在字典中添加一个键值对 新key:value
改:
    字典名[旧key] = value   在字典中修改旧key对应的值为value
删:
    字典名.pop(key): 根据key删除对应的键值对
    del 字典名[key]: 根据key删除对应的键值对
    字典名.clear(): 清空字典中所有元素
    del 字典名: 删除整个字典
查:
    字典名[key]:  根据key获取value
    字典名.get(key):  根据key获取value
    len(字典名): 获取字典中键值对的个数
    字典名.keys(): 获取所有的key
    字典名.values(): 获取所有的values
    字典名.items(): 获取所有的键值对    注意: 每个键值对都单独封装为元组

示例

python
"""字典是可变类型"""
# 定义空字典,存储学生的成绩
score_dict = {}
print(score_dict)    #{}
# 1.增
# 	字典名[新key] = value : 在字典中添加一个键值对 新key:value
score_dict['李四'] = 80
score_dict['王五'] = 90
score_dict['赵六'] = 90
score_dict['张三'] = 99
score_dict['张三'] = 100
score_dict['田七'] = 100
print(score_dict)    #{'李四': 80, '王五': 90, '赵六': 90, '张三': 100, '田七': 100}

# 2.改
# 	字典名[旧key] = value : 在字典中修改旧key对应的值为value
# 需求: 修改王五的成绩为99
score_dict['王五'] = 99
print(score_dict)    #{'李四': 80, '王五': 99, '赵六': 90, '张三': 100, '田七': 100}

# 3.查
# 字典名[key]:  根据key获取value
print(score_dict['张三'])    #100
# 字典名.get(key):  根据key获取value
print(score_dict.get('王五'))    #99
#  len(字典名): 获取字典中键值对的个数
print(len(score_dict))    #5
#  字典名.keys(): 获取所有的key
# 需求: 获取所有的姓名    
names = list(score_dict.keys())
print(names, type(names))    #['李四', '王五', '赵六', '张三', '田七'] <class 'list'>
#  字典名.values(): 获取所有的values
# 需求: 获取所有的分数
scores = list(score_dict.values())
print(scores, type(scores))    #[80, 99, 90, 100, 100] <class 'list'>
#  字典名.items(): 获取所有的键值对  注意: 每个键值对都单独封装为元组
# 需求: 获取所有的键值对
kvs = score_dict.items()
print(kvs)    
# dict_items([('李四', 80), ('王五', 99), ('赵六', 90), ('张三', 100), ('田七', 100)])

# 4.删
# 	字典名.pop(key): 根据key删除对应的键值对
score_dict.pop('张三')
print(score_dict)    #{'李四': 80, '王五': 99, '赵六': 90, '田七': 100}
# 	del 字典名[key]: 根据key删除对应的键值对
del score_dict['王五']
print(score_dict)    #{'李四': 80, '赵六': 90, '田七': 100}
# 	字典名.clear(): 清空字典中所有元素
score_dict.clear()    
print(score_dict)    #{}
# 	del 字典名: 删除整个字典
del score_dict
print(score_dict)  # NameError: name 'score_dict' is not defined

5.4 字典的遍历(注意:字典不支持下标索引,所以同样不可以用while循环遍历

方式1: 直接遍历字典获取key,然后根据key找value
for k in 字典:
    v = 字典[k]
        循环体
方式2: 先获取所有键值对元组,然后对元组拆包分别拿到key和value
for k,v in 字典.items:
    循环体

示例:

# 定义非空字典,要求遍历打印格式为: xx分数是yy
score_dict = {'李四': 80, '王五': 99, '赵六': 90, '张三': 100, '田七': 100}
# 方式1(推荐): 直接遍历字典(默认获取的键)
for k in score_dict:
    # 根据k获取v
    # v = score_dict[k]
    v = score_dict.get(k)
    # 格式化输出
    print(f"{k}的分数是:{v}")

# 方式2(了解): 先获取所有的key,然后遍历依次获取value
for k in score_dict.keys():
    # 根据k获取v
    # v = score_dict[k]
    v = score_dict.get(k)
    # 格式化输出
    print(f"{k}的分数是:{v}")

# 方式3(推荐): 先获取所有的键值对,然后拆包直接拿到k,v
for k, v in score_dict.items():
    # 格式化输出
    print(f"{k}的分数是:{v}")

输出结果:
李四的分数是:80
王五的分数是:99
赵六的分数是:90
张三的分数是:100
田七的分数是:100

5.5  集合的特点总结

1.支持容纳多个元素
2.支持for循环遍历
3.支持修改操作
4.每个元素是键值对:key只能是不可变类型,value可以是任意类型数据
5.没有下标索引->不支持while循环
6.没有下标索引->无序
7.没有下标索引->键不能重复

第三部分、序列详解

五大容器中属于序列的有: 字符串 列表 元组

1.序列支持切片(截取部分内容),格式:

序列[开始索引:结束位置:步长]
注意事项如下:
    1)序列有两套索引: 正索引从0开始从左到右依次递增,负索引从-1开始从右到左依次递减
    2)步长决定截取方向: 正步长代表从左到右,负步长代表从右到左 
    3)开始索引:如果留空,默认代表从头开始
    4)结束位置:结束索引=结束位置-1,如果留空默认代表到尾部(含)结束

注意:此操作不会影响序列本身,而是会得到一个新的序列(列表、元组、字符串)
2.序列支持运算符如下    
+ : 序列+序列: 两个序列内容拼接返回一个新序列
* : 序列*x:表示序列的内容乘以x份放到一个新的序列中返回

注意: +是拼接返回一个新的列表,append是直接修改原有列表

切片示例:

# 定义非空字符串,要求截取'bd'
s = 'abcde'
print(s[1:4:2])

# 定义非空列表,要求截取['b', 'd']
l = ['a', 'b', 'c', 'd', 'e']
print(l[1:4:2])

# 定义非空元组,要求截取('b', 'd')
t = ('a', 'b', 'c', 'd', 'e')
print(t[1:4:2])

运算示例:

# 定义非空字符串
s = 'abcde'
# 定义非空列表
l = ['a', 'b', 'c', 'd', 'e']
# 定义非空元组
t = ('a', 'b', 'c', 'd', 'e')

# + : 序列+序列: 两个序列内容拼接返回一个新序列
print(s + s)
#abcdeabcde
print(l + l)
#['a', 'b', 'c', 'd', 'e', 'a', 'b', 'c', 'd', 'e']
print(t + t)
#('a', 'b', 'c', 'd', 'e', 'a', 'b', 'c', 'd', 'e')
# * : 序列*x:表示序列的内容乘以x份放到一个新的序列中返回
print(s * 2)
#abcdeabcde
print(l * 2)
#['a', 'b', 'c', 'd', 'e', 'a', 'b', 'c', 'd', 'e']
print(t * 2)
#('a', 'b', 'c', 'd', 'e', 'a', 'b', 'c', 'd', 'e')

# 注意: +和append操作列表的区别?
# +是拼接返回一个新的列表
print(l + ['f'])
#['a', 'b', 'c', 'd', 'e', 'f']
# append是直接修改原有列表
l.append('f')
print(l)
#['a', 'b', 'c', 'd', 'e', 'f']

补充切片练习:

以列表示例:

# 定义非空列表
my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']

# 需求: 要求截取新的列表['a', 'b', 'c']
print(my_list[:3])
# 需求: 要求截取新的列表['c', 'd', 'e']
print(my_list[2:5])
# 需求: 要求截取新的列表['e', 'f', 'g']
print(my_list[-3::])
# 需求: 要求截取新的列表['a', 'c', 'e' , 'g']
print(my_list[::2])
# 需求: 要求截取新的列表['b', 'd', 'f']
print(my_list[1::2])
# 需求: 要求把原有列表元素倒序放到新的列表中
print(my_list[::-1])
# 需求: 要求截取新的列表['g', 'f']
print(my_list[-1:-3:-1])
# 需求: 要求截取新的列表['e', 'd' ,'c']
print(my_list[4:1:-1])
# 需求: 要求截取新的列表['c', 'b' ,'a']
print(my_list[2::-1])
# 需求: 要求截取新的列表['g', 'e' ,'c' , 'a']
print(my_list[::-2])
# 需求: 要求截取新的列表['f', 'd' ,'b']
print(my_list[-2::-2])

第四部分:推导式详解

1、什么是推导式

推导式(Comprehension):Python中一种简洁、优雅的语法,用于创建数据结构。它能够通过一行代码生成列表、字典、集合或生成器表达式。

2、支持推导式的容器

Python五大容器中,支持推导式的有三种:列表、集合、字典(其中最常用的是列表推导式)


3、列表推导式

基础语法
[表达式 for 变量 in 可迭代对象]
[表达式 for 变量 in 可迭代对象 if 条件]
示例

python

# 需求1:生成存储了1-10的列表
# 原始方式
nums1 = []
for i in range(1, 11):
    nums1.append(i)
print(nums1)  # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 推导式方式
nums2 = [i for i in range(1, 11)]
print(nums2)  # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


# 需求2:生成一个存储了1-10中偶数的列表
# 原始方式
nums1 = []
for i in range(1, 11):
    if i % 2 == 0:
        nums1.append(i)
print(nums1)  # [2, 4, 6, 8, 10]

# 推导式方式
nums2 = [i for i in range(1, 11) if i % 2 == 0]
print(nums2)  # [2, 4, 6, 8, 10]

# 更复杂的表达式
squares = [i**2 for i in range(1, 6)]
print(squares)  # [1, 4, 9, 16, 25]

# 嵌套循环
pairs = [(x, y) for x in range(3) for y in range(2)]
print(pairs)  # [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]

4、集合推导式

基础语法
{表达式 for 变量 in 可迭代对象}
{表达式 for 变量 in 可迭代对象 if 条件}
示例

python

# 需求:生成存储了1-10的集合
# 原始方式
nums1 = set()
for i in range(1, 11):
    nums1.add(i)
print(nums1)  # {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

# 推导式方式
nums2 = {i for i in range(1, 11)}
print(nums2)  # {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

# 带条件的集合推导式
even_nums = {i for i in range(1, 11) if i % 2 == 0}
print(even_nums)  # {2, 4, 6, 8, 10}

# 对字符串去重
unique_chars = {c for c in "hello world" if c != ' '}
print(unique_chars)  # {'h', 'e', 'l', 'o', 'w', 'r', 'd'}

5、字典推导式

基础语法
{键表达式: 值表达式 for 变量 in 可迭代对象}
{键表达式: 值表达式 for 变量 in 可迭代对象 if 条件}
示例

python

# 需求:生成存储了1:1, 2:2, ... 10:10的字典
# 原始方式
nums1 = {}
for i in range(1, 11):
    nums1[i] = i
print(nums1)  # {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10}

# 推导式方式
nums2 = {i: i for i in range(1, 11)}
print(nums2)  # {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10}

# 更复杂的字典推导式
squares = {i: i**2 for i in range(1, 6)}
print(squares)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# 带条件的字典推导式
even_squares = {i: i**2 for i in range(1, 11) if i % 2 == 0}
print(even_squares)  # {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}

# 从两个列表中创建字典
names = ['张三', '李四', '王五']
scores = [90, 85, 95]
score_dict = {name: score for name, score in zip(names, scores)}
print(score_dict)  # {'张三': 90, '李四': 85, '王五': 95}

6、生成器推导式

python
# 生成器推导式(注意:不是元组推导式)
# 使用小括号是生成器表达式,不是元组推导式
nums = (i for i in range(1, 11))
print(nums)  # <generator object <genexpr> at 0x...>

# 生成器可以迭代
for i in nums:
    print(i, end=' ')  # 1 2 3 4 5 6 7 8 9 10

# 如果想要元组,可以使用tuple()转换
t = tuple(i for i in range(1, 11))
print(t)  # (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

第五部分:五大容器总结对比

1、分类https://%E4%BA%94%E5%A4%A7%E5%AE%B9%E5%99%A8.assets/image-20240822161015396.pnghttps://%E4%BA%94%E5%A4%A7%E5%AE%B9%E5%99%A8.assets/image-20240822161015396.png

列表

元组

字符串

集合

字典

元素数量

支持多个

支持多个

支持多个

支持多个

支持多个

元素类型

任意

任意

仅字符

不可变类型

Key:不可变类型

Value:任意类型

下标索引

支持

支持

支持

不支持

不支持

重复元素

支持

支持

支持

不支持

不支持

数据有序

可修改性

支持

不支持

不支持

支持

支持

使用场景

可修改、可重复的一批数据记录场景

不可修改、可重复的一批数据记录场景

一串字符的记录场景

可修改不可重复的数据记录场景

存储键值对,然后根据KeyValue的数据记录场景


2、通用操作

功能

描述

通用for循环

遍历容器(字典是遍历key

通用拆包操作

拆包容器(字典拆的是key)

len()

容器内元素个数

min()

容器内最小元素

max()

容器内最大元素

sorted(序列, [reverse=True])

排序,reverse=True表示降序

得到一个排好序的列表!!!

示例代码
# 1. 定义五大容器
s = 'cbedaa'                       # 字符串
l = ['c', 'b', 'e', 'd', 'a', 'a'] # 列表
t = ('c', 'b', 'e', 'd', 'a', 'a') # 元组
se = {'c', 'b', 'e', 'd', 'a', 'a'} # 集合
d = {'c': 1, 'b': 1, 'e': 1, 'd': 1, 'a': 1} # 字典

# len()获取容器中元素个数
print(f"字符串: {len(s)}")   # 6
print(f"列表: {len(l)}")     # 6
print(f"元组: {len(t)}")     # 6
print(f"集合: {len(se)}")    # 5(自动去重)
print(f"字典: {len(d)}")     # 5(键的数量)

# min()获取容器中最小元素
print(f"字符串最小: {min(s)}")  # a
print(f"列表最小: {min(l)}")    # a
print(f"字典最小键: {min(d)}")  # a

# sorted(容器)默认升序排序
print(f"字符串排序: {sorted(s)}")        # ['a', 'a', 'b', 'c', 'd', 'e']
print(f"列表排序: {sorted(l)}")          # ['a', 'a', 'b', 'c', 'd', 'e']
print(f"集合排序: {sorted(se)}")         # ['a', 'b', 'c', 'd', 'e']
print(f"字典按键排序: {sorted(d)}")      # ['a', 'b', 'c', 'd', 'e']

# in : 判断指定元素是否在容器中
print(f"'c' in 字符串: {'c' in s}")      # True
print(f"'c' in 列表: {'c' in l}")        # True
print(f"'c' in 集合: {'c' in se}")       # True
print(f"'c' in 字典: {'c' in d}")        # True(判断的是键)

# not in : 判断指定元素是否不在容器中
print('c' not in s)
print('c' not in l)
print('c' not in t)
print('c' not in se)
print('c' not in d)

# 拆包
a, b, c = '123'
print(a, b, c)    #1 2 3
a, b, c = [1, 2, 3]
print(a, b, c)      #1 2 3
a, b, c = (1, 2, 3)
print(a, b, c)      #1 2 3
a, b, c = {1, 2, 3}
print(a, b, c)      #1 2 3
a, b, c = {1: 'a', 2: 'a', 3: 'a'}
print(a, b, c)      #1 2 3

3、容器转换

功能

描述

list()

转换为列表

tuple()

转换为元组

str()

转换为字符串

set()

转换为集合

示例代码

# 定义非空列表
l = [2, 1, 3, 1]
# 定义非空元组
t = (2, 1, 3, 1)
# 定义非空字符串
s = '2131'
# 定义非空集合
ss = {2, 1, 3, 1}
# 定义非空字典
d = {2: 'a', 1: 'a', 3: 'a', 1: 'a'}

# list(其他容器): 把其他容器转换为列表
print(list(t))
print(list(s))
print(list(ss))
print(list(d))
print('----------------')
# tuple(其他容器): 把其他容器转换为元组
print(tuple(l))
print(tuple(s))
print(tuple(ss))
print(tuple(d))
print('----------------')
# set(其他容器): 把其他容器转换为集合
print(set(l))
print(set(t))
print(set(s))
print(set(d))
print('----------------')
# str(其他容器): 把其他容器转换为字符串
print(str(l))  # '[2, 1, 3, 1]'
print(str(t))  # '(2, 1, 3, 1)'
print(str(ss))  # '{1, 2, 3}'
print(str(d))  # "{2: 'a', 1: 'a', 3: 'a'}"
print('----------------')

# TODO 需求: 上述的字符串结果,如何再转换回去?
print(list('[2, 1, 3, 1]'))  # 结果是有问题的
print(tuple('(2, 1, 3, 1)'))  # 结果是有问题的
print(set('{1, 2, 3}'))  # 结果是有问题的
# print(dict("{2: 'a', 1: 'a', 3: 'a'}")) # 结果报错
print('-----------------------------------------------------------')

# TODO 拓展:
# TODO 思路: 如何把引号去掉? 
#方式1: 手动删除两端引号   
#方式2: eval(字符串)自动去除引号
print(eval('[2, 1, 3, 1]'))  # 结果转为列表
print(eval('(2, 1, 3, 1)'))  # 结果转为元组
print(eval('{1, 2, 3}'))  # 结果转为集合
print(eval("{2: 'a', 1: 'a', 3: 'a'}"))  # 结果转为字典
print('-----------------------------------------------------------')
# eval可以把字符串中是整数,浮点数,布尔值的变成本身类型
print(eval('10'))
print(eval('3.14'))
print(eval('True'))
# 但是eval不要直接去除非整数,浮点数,布尔值,容器以外的引号!!!
# print(eval('你好')) # 报错

今天的内容就到这里啦,希望对大家有所帮助,有错误的地方欢迎各位指正!

更多推荐