容器类数据类型
字符串
字符串定义
单引号:单引号与双引号作用一致, 如果字符串内有单引号则需要用双引号, 如果字符串内有双引号则需要用单引号
三引号: 在双引号和单引号的基础上增加了可以换行和缩进等
转义字符: '\'':可以直接输出单引号
s1 = '123' s2 = "1223" s3 = ''' select * from student ''' s4 = """ select * from student """ s5 = "I'm Python" s6 = 'I\'m Python' print(s1) print(s2) print(s3) print(s4) print(s5) print(s6)
字符串索引和切片
序列名称[开始位置下标:结束位置下标:步长(步阶)]
不包含结束位置下标对应的数据, 正负整数均可;
步长是选取间隔,正负整数均可,正数从左向右,负数从右向左。
默认步长为1, 逆向开始为-1
索引:
str1 = '01234567' print(len(str1)) print('*' * 30) print(str1[0]) print(str1[1]) print(str1[2]) print(str1[3]) print('*' * 30) # 直接遍历 for i in str1: print(i) print('*' * 30) # 下标遍历 for i in range(len(str1)): print(str1[i]) print('*' * 30)
切片:
概述: 字符串切片指的是 从字符串中 截取出指定的部分内容. 格式: 字符串变量名[起始索引:结束索引:步长]
格式解释: 1. 起始索引表示从哪里开始切(截取), 默认是: 0(正向索引时), -1(反向索引时) 包括: 起始索引(处的字符). 2. 结束索引表示到哪里结束, 默认是: 字符串长度 - 1 (正向索引时), 逆向索引时: 字符串长度的负数形式 不包括: 结束索引(处的字符).
3. 步长表示每次截取字符的间隔, 默认是:
细节:
如果起始索引 -> 结束索引的方向 和 步长的方向不一致, 则: 获取不到数据.
切片的特殊写法, 字符串变量名[::-1] 表示: 字符串反转.
例如: 字符串值: a b c d e f g 正向索引: 0 1 2 3 4 5 6 逆向索引: -7 -6 -5 -4 -3 -2 -1
# 1. 自定义变量, 记录字符串值. s1 = 'abcdefg' # 2. 演示字符串切片: 正向索引. print(s1[1:5]) # bcde print(s1[1:5:1]) # 效果同上, 即: 默认的步长就是 1 print(s1[1:5:2]) # bd print(s1[::]) # 获取字符串本身, 它等价于: s1[0:(6 + 1):1] print(s1[0:(6 + 1):1]) # 效果同上. print(s1[:3]) # 不写起始索引, 正向步长时, 默认是: 0, 等价于: s1[0:3:1] print(s1[2:]) # 不写结束索引, 正向步长时, 默认是: 长度 + 1, 等价于: s1[2:7:1] print(s1[2::2]) # ceg print('-' * 30) # 3. 演示字符串切片: 逆向索引. print(s1[::-1]) # 逆向时, 起始索引: 默认是: -1, 结束索引: 默认是: 长度+1的负数形式. gfedcba print(s1[-1:-8:-1]) # 效果同上 print(s1[-2:-6:-2]) # fd print(s1[0:3:-1]) # 获取不到数据, 但是不报错, 因为: 起始索引 -> 结束索引的方向 和 步长的方向不一致. print(s1[:-3:-1]) # gf print(s1[:2:-1]) # gfed, 很重要. print(s1[1:-1:2]) # bdf print(s1[4:-6]) # 无数据, 顺序不一致. print('-' * 30)
字符串操作方法:
字符串函数介绍: 就是Python提供的, 可以直接操作 字符串变量 或者 字符串值的一些函数.
查找
概念:
""" 字符串变量名.find(要查找的子串, 起始索引, 结束索引) 找子串在字符串中第一次出现的位置, 找到就返回子串的起始索引, 找不到就返回-1 字符串变量名.index(要查找的子串, 起始索引, 结束索引) 找子串在字符串中第一次出现的位置, 找到就返回子串的起始索引, 找不到就报错. 字符串变量名.rfind(要查找的子串, 起始索引, 结束索引) 找子串在字符串中最后一次出现的位置, 找到就返回子串的起始索引, 找不到就返回-1 字符串变量名.rindex(要查找的子串, 起始索引, 结束索引) 找子串在字符串中最后一次出现的位置, 找到就返回子串的起始索引, 找不到就报错. """
代码:
# 1. 定义变量, 记录字符串值. # 0 13 25 s1 = 'hello python hello world hello sql' # 2. 查找 hello 字符串在 s1中出现的索引. # find()函数 print(s1.find('hello')) # 0, 不写起始和结束索引, 默认是在 整个字符串中 查找的. print(s1.find('hello', 2)) # 从索引2的位置处, 开始查找. print(s1.find('hello', 2, 17)) # -1, 因为是在 索引 2 ~ 17位置查找, 包左不包右. print('-' * 30) # index()函数 print(s1.index('hello')) # 0, 效果同上 print(s1.index('hello', 2)) # 13, 效果同上. # print(s1.index('hello', 2, 17)) # 找不到就: 报错. print('-' * 30) # rfind()函数, 最后一次出现的位置, 找不到返回 -1 print(s1.rfind('hello')) # 25 print(s1.rfind('hello', 2)) # 25 print(s1.rfind('hello', 2, 17)) # -1 print('-' * 30) # rindex()函数, 最后一次出现的位置, 找不到: 报错 print(s1.rindex('hello')) # 25 print(s1.rindex('hello', 2)) # 25 # print(s1.rindex('hello', 2, 17)) # 报错. print('-' * 30)
扩展需求:
找大串中, 小串出现的次数.至少3种解题思路.
max_str = "hello python hello world hello sql"min_str = 'hello'
s1 = 'hello world hello python hello java' s2 = 'hello' # 方式1: find() cnt = 0 while True: idx = s1.find(s2) if idx == -1: break cnt += 1 s1 = s1[idx + len(s2):] print(cnt) # 方式2: 按小串切割字符串, 最后长度减一 print(len(s1.split(s2)) - 1) # 方式3:用空字符修改原字符串, 用原字符串长度减新字符串长度再除以子串长度 new_str = s1.replace(s2, '') cnt = (len(s1) - len(new_str)) // len(s2) print(cnt) # 用原字符串.count(子串)方法统计个数 cnt = s1.count(s2) print(cnt)
KMP改进
找出所有子串的起始位置
替换和切割
字符串变量名.replace(旧子串, 新子串, 替换次数) 用新的替换旧的, 且可以设置替换几个(如超出真实旧子串个数, 则以实际为准) 字符串变量名.split(分隔符, 切割次数) 按照分隔符切割, 且可以设置切割次数(如超出真实切割次数, 则以实际为准) 细节: 因为字符串属于 不可变数据类型, 所以上述的函数操作字符串后, 会返回1个新的结果, 即: 旧字符串不变.
替换案例:
# 1. 定义变量, 记录字符串内容. s1 = 'hello python hello sql hello pandas' # 2. 用 heima 来替换上述的 hello. s2 = s1.replace('hello', 'heima') # 如果不写个数, 则会一次性替换所有. s3 = s1.replace('hello', 'heima', 2) # 只会替换2次(前2个) s4 = s1.replace('hello', 'heima', 5) # 超出真实个数, 则以实际为准. # 3. 打印结果. print(f's1: {s1}') # hello python hello sql hello pandas print(f's2: {s2}') # heima python heima sql heima pandas print(f's3: {s3}') # heima python heima sql hello pandas print(f's4: {s4}') # heima python heima sql heima pandas print('-' * 30)
切割案例:
# 1. 定义变量, 记录字符串内容. s1 = 'hello python hello sql hello pandas' # 2. 测试split()函数. s5 = 'hello python hello sql hello pandas' list1 = s5.split(' ') # 切割后, 获取的是一个 字符串形式的列表, 即: ['hello', 'python', 'hello'...] list2 = s5.split(' ', 2) # 按空格切割, 只会切割2次(前2个), 即: 获取的元素个数为: 2 + 1 = 3个. list3 = s5.split(' ', 9) # 如果切割的个数超过真实个数, 则以实际为准. # 3. 打印结果. print(f's5: {s5}') # hello python hello sql hello pandas print(f'list1: {list1}') # ['hello', 'python', 'hello', 'sql', 'hello', 'pandas'] print(f'list2: {list2}') # ['hello', 'python', 'hello sql hello pandas'] print(f'list3: {list3}') # ['hello', 'python', 'hello', 'sql', 'hello', 'pandas']
字符串练习题
输入一个字符串,打印所有偶数位上的字符(下标是0,2,4,6…位上的字符)
# 1. 键盘录入字符串, 并接收. s1 = input("请输入一个字符串: ") # 假设: s1 = 'abcde' # 2. 通过for循环, 获取字符串中每个字符的索引. for i in range(len(s1)): # 3. 判断当前的索引值是否是偶数, 如果是, 就输出该字符. if i % 2 == 0: # 走这里, 说明是偶数索引, 打印其值即可. print(s1[i]) print('-' * 30) # 上述格式的优化版, 思路2: 直接获取偶数位索引即可. for i in range(0, len(s1), 2): # i就是字符串s1中的每个 偶数索引. print(s1[i]) print('-' * 30) # 一步到位: 切片. s2 = s1[::2] print(s2) print('-' * 30)
给定一个文件名,判断其尾部是否以".png"结尾
# 练习2: # 方式1:切片 fileName = input('输入文件名:') endName = input('请输入文件结尾:') if fileName[-len(endName):] == endName and len(fileName) > len(endName): print(f'文件名{fileName}是以{endName}结尾') else: print(f'文件名{fileName}不是以{endName}结尾') # 方式2:rfind() fileName = input('输入文件名:') endName = input('请输入文件结尾:') end = fileName.rfind(endName) if end == len(fileName) - len(endName) and len(fileName) > len(endName): print(f'文件名{fileName}是以{endName}结尾') else: print(f'文件名{fileName}不是以{endName}结尾')
模拟登录, 只给3次机会.
# 1. 定义变量, 记录: 正确的账号和密码, 注意: 这里只是模拟, 实际开发中, 这样的数据是存储在数据库中的. username, password = 'admin01', 'pwd111' # 2. 因为不知道用户多少次能录入正确, 我们用循环, 因为次数固定, 所以使用for循环. for i in range(3): # i的值: 0, 1, 2 # 3. 提示用户录入账号, 密码, 并接受. uname = input('请录入您的账号: ') pwd = input('请录入您的密码: ') # 4. 判断是否登录成功. if uname == username and pwd == password: print(f'登陆成功, 欢迎您, {uname}') # 核心细节: break break else: # 走这里, 说明登陆失败, 判断是否还有试错机会. # 分解版. # if i == 2: # print('账号或密码录入错误次数已达上限, 请于管理员联系!') # else: # print(f'账号或密码错误, 您还有 {2 - i} 次机会, 请重新输入!') # 合并版. print('账号或密码录入错误次数已达上限, 请于管理员联系!' if i == 2 else f'账号或密码错误, 您还有 {2 - i} 次机会, 请重新输入!') print('-' * 30)
扩展: in, not in 判断指定的字符是否在字符串中的.
s1 = 'abcdef' # 判断 abc 是否在 字符串s1中, 必须是连续的, 区分大小写. print('abc' in s1) # True print('bcd' in s1) # True print('bce' in s1) # False print('Abc' in s1) # False print('-' * 30) print('abc' not in s1) # False print('bcd' not in s1) # False print('bce' not in s1) # True print('Abc' not in s1) # True
扩展练习
交换变量
交换两个变量值. 场景1: 字符串变量值交换. 2种思路 s1 = 'aa' s2 = 'bb'
s1 = 'bb' s2 = 'aa'
场景2: 整数变量值交换. 4种思路(包括上述的2种思路) a = 10 b = 20
""" 场景1: 字符串变量值交换. 2种思路 s1 = 'aa' s2 = 'bb' s1 = 'bb' s2 = 'aa' """ s1 = 'aa' s2 = 'bb' # 思路1: 临时变量 tmp = s1 s1 = s2 s2 = tmp print(f's1:{s1}') print(f's2:{s2}') # 思路2: 元组拆包 s1, s2 = s2, s1 print(f's1:{s1}') print(f's2:{s2}') # 思路3: 合并后切片 s3 = s1 + s2 s1 = s3[-len(s2):] s2 = s3[:len(s1)] print(f's1:{s1}') print(f's2:{s2}') """ 场景2: 整数变量值交换. 4种思路(包括上述的2种思路) a = 10 b = 20 """ # 思路1: 临时变量 a = 10 b = 20 tmp = a a = b b = tmp print(f'a:{a}') print(f'b:{b}') # 思路2: 元组拆包 a, b = b, a print(f'a:{a}') print(f'b:{b}') # 思路3: 数值相加减 a += b # a=30 b = a - b # b=10 a = a - b # a=20 print(f'a:{a}') print(f'b:{b}') # 思路4: 异或 a = a ^ b b = a ^ b # a^(b^b) => a a = a ^ b # (a^a)^b => b print(f'a:{a}') print(f'b:{b}')
字符串逆序
键盘录入1个字符串, 对其内容进行反转并打印结果.例如:
键盘录入: abc 反转后结果为: cba
3种解题思路.
""" 键盘录入1个字符串, 对其内容进行反转并打印结果. 例如: 键盘录入: abc 反转后结果为: cba 3种解题思路. """ str1 = input('请输入内容:') # 方式1: 循环遍历字符串,逆序添加到新字符串中 j = len(str1) - 1 str2 = '' while j >= 0: str2 += str1[j] j -= 1 print(str2) print('*' * 30) # 方式2: 逆序切片 print(str1[::-1]) print('*' * 30) # 方式3: 反转字符串添加到新字符串中 print(''.join(reversed(str1))) # 方式4 # 定义左右指针 list1 = list(str1) i = 0 j = len(list1) - 1 # 当左指针位置小于右指针时执行循环 while i < j: # 交换左右指针所指位置元素 tmp = list1[i] list1[i] = str1[j] list1[j] = tmp j -= 1 i += 1 print(''.join(list1)) # 方式5 i = 0 for i in range(len(list1) // 2): list1[i], list1[len(list1) - 1 - i] = list1[len(list1) - 1 - i], list1[i] print(''.join(list1))
全排列
问1, 2, 3, 4这四个数字能组合成的4位数有几种情况, 将所有的组合结果按照3个一行的格式打印到控制台上.
要求1: 该四位数必须同时包含1, 2, 3, 4这四个数字, 即:1234, 1243均可, 1122不行.要求2: 在上述要求基础上, 加入: 数字1和3不能挨着. 即: 1324, 3124均不可. 1234 1432 可以.要求3: 在上述要求基础上, 加入: 数字4不能开头, 即: 4321不行.要求4: 在上述要求基础上, 加入: 代码行数不超过7行.
cnt = 0 for i in range(1234, 4322): s = str(i) if '1' in s and '2' in s and '3' in s and '4' in s: cnt += 1 print(i, end='\n' if cnt % 3 == 0 else '\t')
统计字符个数
需求:
键盘录入1个字符串, 然后统计字符串中每个字符出现的次数. 例如: 录入 'aaabbaaccb' 输出结果为: a(5)b(3)c(2) 变形: 键盘录入字符串, 分别统计其中 大写字母, 小写字母, 数字的个数, 并打印结果.
代码:
# 方式1 str1 = 'aaabbaaccb' # 将用户输入的字符串转换为列表 str_list = list(str1) # 将用户输入的字符串转换为集合(去重) str_set = set(str_list) # 遍历集合 for i in str_set: # 输出结果(ps:集合会导致每次输出的顺序不一致) print(f'{i}({str_list.count(i)})', end='') print('') print('-' * 30) # 方式2 str1 = 'aaabbaaccb' # 将用户输入的字符串转换为列表 str_list = list(str1) # 定义空列表存储未出现过的字符 num_list = [] # 遍历字符串列表 for i in str_list: # 判断当前字符串是否在数字列表中 if i not in num_list: # 不在则将其添加到数字列表中 num_list.append(i) # 输出结果 print(f'{i}({str_list.count(i)})', end='') print('')
列表
可变类型的数据容器, 建议存储同类型数据, 即: 其元素值是可以直接修改的.
列表的定义
list1 = [值1, 值2, 值3......] list2 = [] list3 = list()
列表的定义 , 索引与遍历
索引
概念
和字符串一样, 列表也有自己的编号(索引, 脚标, 索引, index), 并且默认从0开始, 同时也支持切片, 用法和字符串一样.
格式
list1[索引下标]
# 需求1: 演示定义列表. # 1. 定义列表. # 列表可以同时存储多个不同类型的值, 但是建议同时存储多个同类型的值,因为: 好管理. list1 = [10, 20, 10.3, True, False, 'abc'] list2 = [] # 如果定义空列表, 推荐使用这种写法. list3 = list() # 2. 查看列表内容. print(list1) print(list2) print(list3) # 3. 查看变量的 类型 print(type(list1)) # <class 'list'> print(type(list2)) # <class 'list'> print(type(list3)) # <class 'list'> print("-" * 30) # 需求2: 演示列表的索引操作. list4 = [1, 2, 3, 4, 5] # 根据索引获取元素. print(list4[0]) print(list4[1]) # 列表属于可变类型, 所以其值是可以改变的. list4[2] = 300 print(list4) # [1, 2, 300, 4, 5]
遍历(迭代: iterator)
遍历:
Python中, 我们把逐个获取容器类型中 每个元素值的过程, 称之为: 遍历, 也叫: 迭代(Iterator)
列表遍历介绍: 概述: 列表遍历指的是 逐个获取列表中元素值的过程. 思路: 方式1: 直接获取列表的每个元素值. 方式2: 通过索引的方式获取列表的元素值.
# 1. 定义列表 list1 = ['a', 'b', 'c', 'd'] # 2. 遍历列表. # 方式1: 直接获取列表的每个元素值. for i in list1: print(i) print('-' * 30) # 方式2: 通过索引的方式获取列表的元素值. # for循环写法. for i in range(len(list1)): # i的值: 0, 1, 2, 3 print(list1[i]) print('-' * 30) # while循环写法 i = 0 while i < len(list1): print(list1[i]) i += 1 print('-' * 30)
扩展列表嵌套:
# 扩展: 列表的嵌套. list2 = [[10, 20, 30], [40, 50], [60, 70, 80, 90]] # 如何获取 50? print(list2[1][1]) # 如何修改 60 => 666 list2[2][0] = 666 print('-' * 30) # 如何遍历上述的列表嵌套形式. # 思路1: 直接获取元素值. for inner_list in list2: # 因为 inner_list 还是1个列表, 所以我们接着遍历. # print(inner_list) for value in inner_list: print(value, end='\t') print() # 打印完1个列表后, 记得加换行. print('-' * 30) # 思路2: 根据索引获取元素值. for i in range(len(list2)): # print(i) # 0, 1, 2 分别代表list2列表的 3个子列表的索引. # print(list2[i]) # list2[i] 就是列表list2的每个 子列表, 我们接着遍历. for j in range(len(list2[i])): # 具体的获取元素值的过程, 并打印. print(list2[i][j], end='\t') print()
列表的操作
增加
概念:
append(元素) 向列表尾追加元素(任意变量)
extend(必须是容器变量) 把容器类型中的每个变量都添加到 列表中
insert(索引, 元素) 向列表的指定位置插入元素
(索引不合法:最前或最后 => 可以越界)
append() 和 extend()的区别: 区别1: 参数要求不同. append(): 可以传入 任意变量. extend(): 必须传入 容器类型. 区别2: 作用不同. append(): 把元素追加到末尾, 默认是 当做1个整体 来添加的. extend(): 把容器类型的每个元素, 逐个添加进来, 底层有遍历的动作. insert()函数是往指定的位置插入数据, 如果索引值不合法, 则会默认添加到 最前 或者 最后, 具体要看下的索引值.
格式代码:
# 需求1: 演示列表相关操作 增. # 1. 定义列表. list1 = ['a', 'b', 'c'] # 2. 演示 增 相关的函数. # 列表名.append(任意变量即可) 往列表的末尾追加元素. list1.append('d') list1.append('e') list1.append('xyz') # 是把 'xyz'当做整体来添加的. list1.append([10, 20, 30]) # 是把 列表 当做整体来添加的. # 列表名.extend(必须是容器变量) 把容器类型中的每个变量都添加到 列表中. list1.extend(10) # 报错. list1.extend('xyz') # 字符串 = 容器类型. list1.extend([10, 20, 30]) # 字符串 = 容器类型. # 列表名.insert(索引, 元素) 往列表的指定位置插入元素. list1.insert(1, 'd') # 往 索引1的(前边)位置插入元素 d list1.insert(-2, 'd') # 往 索引-2的(前边)位置插入元素 d # 3. 打印结果. print(f'list1: {list1}') print('-' * 30)
删除
概念:
del 列表名[索引] #删除列表中的某个元素 无返回
del 列表名 #在内存中删除整个列表, 相当于未定义过该列表
pop([索引]) #删除指定下标的数据, 默认为最后一个
remove(元素) #删除指定元素(第一个匹配的元素) 无返回
clear() #删除列表所有元素, 返回空列表 => list1 = [ ]
格式代码:
# 需求3: 演示列表相关操作 删. # 1. 定义列表, 记录元素. list1 = ['a', 'b', 'c', 'd', 'b', 'd'] print(f'删除前: {list1}') # 2. 测试上述的方法. # 列表名.pop(索引) 删除指定索引位置的元素, 并返回被删除的元素. # print(list1.pop(2)) # c # print(list1.pop(5)) # 正常是可以的, 但是这里是报错, 因为上边删了一个元素, 就没有索引5了 # print(list1.pop(10)) # IndexError, 索引越界错误. # 列表名.remove(元素) 删除指定元素, 删除第一个找到的元素. # list1.remove(0) # ValueError, revmoe是根据元素值删除的. # print(list1.remove('b')) # 删除第1个匹配到的'b', 无任何返回, 如果打印, 结果是: None # list1.remove('b') # 正确 # del 列表名[索引] 删除指定索引位置的元素. del(list1[2]) del list1[2] # 写法同上. # del 列表名 从内存中删除整个列表, 相当于该列表从未定义. # del list1 # del(list1) # 写法同上. # 列表名.clear() 清空列表, 得到1个 空列表, 类似于: list1 = [] # list1.clear() # 3. 打印结果. print(f'删除后: {list1}') print('-' * 30)
修改
概念:
一维: 列表名[索引] = 新值 二维: 列表名[索引][索引] = 新值
排序关键字 是否反转(默认不反转)
列表名.sort(key = None, reverse = False) 对列表进行排序(按关键字, 升序)
列表名.reverse() 将数据序列反转
格式代码:
# 需求4: 演示列表相关操作 改. # 1. 定义列表, 记录元素. list1 = ['a', 'b', 'c', 'd', 'b', 'd'] print(f'修改前: {list1}') # 2. 演示列表的 改 相关操作. # 列表名[索引] = 值 # list1[1] = 100 # 列表名.reverse() 反转列表元素内容. # list1.reverse() # 扩展, 你可以通过 for循环 或者 while循环的方式, 自定义代码对列表内容进行反转. # 列表名.sort(key=None, reverse=False) 列表元素排序, key可以指定排序规则(后边讲), reverse表示升序还是降序, 默认是False(升序) # list1.sort() # list1.sort(reverse=False) # 效果同上, False = 不反转, 即: 升序. list1.sort(reverse=True) # True = 反转, 即: 降序. # 3. 打印结果. print(f'修改后: {list1}')
查询
概念:
包左 不包右
列表名.index(元素, 起始索引, 结束索引) 找到返回第一次出现位置, 未找到报错
列表名.count(元素) 统计个数
in 判断元素是否在列表中
not in 判断元素是否不在列表中
格式代码:
# 需求2: 演示列表相关操作 查. # 1. 定义列表. list1 = ['a', 'b', 'c', 'd', 'b', 'd'] # 2. 演示列表的 查找 相关的函数. # 列表名.index(元素, 起始索引, 结束索引) 去列表中查找指定的元素(第一次出现的位置), 找到就返回, 找不到就: 报错. print(list1.index('b')) # 1 print(list1.index('b', 2)) # 4, 从索引2开始查找, 元素b 在列表中的索引 # print(list1.index('b', 2, 4)) # 在索引区间 2 ~ 4之间查找 元素b, 包左不包右, 找不到就 报错. print('-' * 30) # 列表名.count(元素) 计数. print(list1.count('b')) # 2次 # 变量名或者元素值 in 列表名 是否在. print('d' in list1) # True print(10 in list1) # False # 变量名或者元素值 not in 列表名 是否不在. print('d' not in list1) # False print(10 not in list1) # True print('-' * 30)
综合案例
需求:
定义列表, 记录一些姓名. 然后提示用户键盘录入要查找的姓名, 判断列表中是否有该元素, 并打印结果.
代码:
# 1. 定义列表, 记录元素. name_list = ['张三', '李四', '王五', '赵六', '钱七'] # 2. 提示用户键盘录入要查找的姓名, 并接收. search_name = input('请输入要查找的姓名: ') # 3. 判断列表中是否包含该名字, 并提示. if search_name in name_list: print(f'{search_name} 在列表中 存在!') else: print(f'{search_name} 在列表中 不存在!')
扩展练习
删除列表中重复的'cc':
需求:
键盘录入字符串, 并添加到列表中. 输入end结束录入. 然后删除列表中所有的 cc 字符串, 然后按照字典序对元素值进行升序排列. 例如: list1 = ['bb', 'aa', 'cc', 'cc', 'cc', 'dd', 'cc'] 删除后为: list2 = ['aa', 'bb', 'dd']
代码:
# 方式1: 全部录入列表 # 定义空列表list1存储用户输入的字符串 list1 = [] # 定义死循环实现用户重复输入 while True: # 定义字符串型变量str1用来临时接收用户的输入信息 str1 = input('请输入字符串:') # 判断用户输入是否为'end' if str1 == 'end': # 是则跳出循环 break else: # 否则将用户输入添加到列表中 list1.append(str1) # 判断用户输入是否为空 list1_len = len(list1) if list1_len: # 遍历列表将'cc'取出 i = 0 while i < list1_len: if list1[i] == 'cc': list1.pop(i) else: i += 1 # 对列表进行排序 list1.sort() print(list1) # 方式2: 将'cc'不录入列表 # 定义空列表list1存储用户输入的字符串 list1 = [] # 定义死循环实现用户重复输入 while True: # 定义字符串型变量str1用来临时接收用户的输入信息 str1 = input('请输入字符串:') # 判断用户输入是否为'end' if str1 == 'end': # 是则跳出循环 break elif str1 != 'cc': # 否则将用户输入添加到列表中 list1.append(str1) # 判断用户输入是否为空 list1_len = len(list1) if list1_len: # 对列表进行排序 list1.sort() print(list1)
输入数字生成列表和幸运列表
需求:
幸运数字6: 输入任意数字,如数字8,生成nums列表,元素值为1~8,从中选取幸运数字(能够被6整除)移动到新列表lucky,打印nums与lucky。
代码:
# 方式1: # 定义num变量接收用户输入的额熟悉, 并将接收结果转换为整数型 num = int(input('请输入一个整数:')) # 根据用户输入的数字创建列表,1~num nums = [i for i in range(1, num + 1)] # 定义空列表用来存储满足要求的幸运数字 lucky = [] # 判断输入是否小于6 if num < 6: print(f'nums:{nums}') print('No lucky') else: # 大于6时遍历nums列表 for i in nums: # 将能被6整除的数字添加到幸运列表 if i % 6 == 0: lucky.append(i) print(f'nums:{nums}') print(f'lucky:{lucky}') # 方式2: # 定义num变量接收用户输入的额熟悉, 并将接收结果转换为整数型 num = int(input('请输入一个整数:')) # 根据用户输入的数字创建列表,1~num nums = [i for i in range(1, num + 1)] # 判断输入是否小于6 if num < 6: print(f'nums:{nums}') print('No lucky') else: # 幸运数字可以被6整除,根据输入的数字除以6取整 lucky_num = num // 6 # 根据除以6获取的整数创建列表 lucky = [6 * i for i in range(1, lucky_num + 1)] print(f'nums:{nums}') print(f'lucky:{lucky}')
老师分配教室:
需求:
列表嵌套: 有3个教室[[],[],[]],8名讲师['A','B','C','D','E','F','G','H'],将8名讲师随机分配到3个教室中
代码:
import random # 定义教室列表 room = [[], [], []] # 定义教师列表 teacher = ['A','B','C','D','E','F','G','H'] # 遍历教师列表 for i in teacher: # 为教师随机挑选教师 tr = random.randint(0, 2) # 将教师添加到教室列表中 room[tr].append(i) print(room)
元组tuple(定义后不可修改)
元组属于容器类型的一种,可以同时存储 多个元素, 但 元组内容是 不可以发生改变
细节:元组嵌套列表可以修改列表中的元素, 但是修改后的内存地址不变
定义
如果元组只有1个元素, 则该元素后必须加 逗号.如果元组只有1个元素, 且后边没有加 逗号, 那就说明它就是1个该类型的变量.
格式:
tuple1 = (1, 2, 3, 4, 5) tuple
tuple12 = tuple() tuple
tuple3 = () tuple
tuple4 = (10,) tuple
tuple5 = (10) int
代码:
# 需求1: 演示如何定义元组. # 1. 演示如何定义元组. tuple1 = (10, 20, 30, 40, 50) tuple2 = tuple() tuple3 = () tuple4 = (10,) tuple5 = (10) tuple6 = ('aa') # 2. 打印上述的变量. print(tuple1) # (10, 20, 30, 40, 50) print(tuple2) # () print(tuple3) # () print(tuple4) # (10,) print(tuple5) # 10 print(tuple6) # aa # 3. 打印上述的变量的 数据类型. print(type(tuple1)) # <class 'tuple'> print(type(tuple2)) # <class 'tuple'> print(type(tuple3)) # <class 'tuple'> print(type(tuple4)) # <class 'tuple'> print(type(tuple5)) # <class 'int'> print(type(tuple6)) # <class 'str'> print('-' * 30)
索引和切片
索引:
就是索引, 元组和列表, 字符串一样, 每个元素都是有下标的, 且默认是从 0 开始.
print(tuple1[2]) => 3
切片:
元组支持切片, 写法和 列表, 字符串一致.
tuple1[2:5] => 3, 4, 5
代码:
# 需求2: 演示元组的 索引 和 切片操作. tuple7 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) # 根据索引, 获取 元组的元素值. print(tuple7[3]) # 4 # 尝试修改元组的元素值. # tuple7[3] = 200 # 报错, 因为元组内容是 不可变 的. # 元组切片. print(tuple7[2:6]) # [3, 4, 5, 6] # 打印元组的内容. print(f'tuple7: {tuple7}') print("-" * 30)
操作
格式:
tuple1.index(3) => 2
tuple1.count(3) => 3
len(tuple1) => 7
代码:
# 需求3: 元组的常用函数. tuple8 = (1, 2, 3, 4, 5, 3, 5) print(tuple8.index(3)) # 2, 第一次出现的位置. # print(tuple8.index(30)) # 找不到就报错. print(tuple8.count(3)) # 2次 print(f'元组的长度为: {len(tuple8)}') # 7 print("-" * 30)
案例
需求:
修改元组中列表的元素
代码:
t1 = (1, 2, 3, ['a', 'b', 'c']) print(f'修改前: {t1}') # 需求, 把 'b' => 'AI30期' # print(t1[3]) t1[3][1] = 'z' print(f'修改后: {t1}')
字典
数据容器的一种, 用于存储多个元素, 存储形式未键值对形式
特点: 键唯一, 值不唯一
定义
格式:
dict1 = {键 : 值1, 键 : 值2......}
dict2 = dict()
dict3 = {}
代码:
# 1. 演示如何定义字典. # 键 值 键 值 键值对数据 dict1 = {'name': '张三', 'age': 23, 'gender': 'male'} dict2 = dict() dict3 = {} dict4 = {10, 20, 30, 40, 50} # 这个可不是字典, 而是1个集合(set) # 2. 打印字典. print(dict1) print(dict2) print(dict3) print(dict4) # 3. 打印字典的类型. print(type(dict1)) # <class 'dict'> print(type(dict2)) # <class 'dict'> print(type(dict3)) # <class 'dict'> print(type(dict4)) # <class 'set'>
操作方法
# 1. 定义字典, 添加元素. dict1 = {'杨过': '大雕', '郭靖': '杨康', '计宇东': '王二麻子'}
增/改
字典名[键] = 值 => 键存在则覆盖, 不存在则新增
# 2. 演示上述的函数. # 增 dict1['乔峰'] = '阿朱' # 键不存在就添加 dict1['阿紫'] = '阿朱' # 键不存在就添加 # 改 dict1['郭靖'] = '黄蓉' # 键存在, 就覆盖(用新值 覆盖 旧值)
删除
del 字典名['键名'] 删除该键值对
del 字典名 在内存中删除整个字典, 相当于未定义过该列表
clear()
# 删 del dict1['郭靖'] # 根据键, 删除 该键值对. # del(dict1['郭靖']) # 键不存在, 就报错. # del dict1 # 从内存中删除dict1, 相对摧毁(等价于 从未定义)
查询
get(key) 根据键返回默认值, 默认值不写未:None(键不存在返回None).
keys() 返回所有键
values() 返回所有的值
items() 获取所有键值对, 并封装成列表嵌套元组形式返回=>[(k, v), (k, v)]
# 查 # get(键名, 默认值) 根据键获取其对应的值, 如果不存在就返回默认值, 默认值不写即为: None print(dict1.get('阿朱')) # 阿朱是值, 不是键, 所以不存在该键, 返回None print(dict1.get('阿朱', '段誉')) # 阿朱是值, 不是键, 所以不存在该键, 返回 默认值 段誉 print(dict1.get('计宇东')) # keys() 获取所有的键. print(dict1.keys()) # dict_keys(['杨过', '计宇东', '乔峰', '阿紫']) # values() 获取所有的值 print(dict1.values()) # dict_values(['大雕', '王二麻子', '阿朱', '阿朱']) # items(), 获取所有的键值对数据, 并封装成: 列表嵌套元组的形式. # 格式: [(键, 值), (键, 值)...] print(dict1.items()) # 打印结果. print(dict1)
遍历案例
需求: 演示如何遍历字典, 即: 逐个的获取字典中键值对的过程.
定义字典, 记录元素. dict1 = {'name': '乔峰', 'age': 41, 'gender': '男', 'kongfu': '降龙十八掌'}
思路1:
根据键获取对应的值
# 思路1: 根据 键 获取其对应的 值. 理解为: 根据丈夫 找 妻子. # step1: 获取所有的键. keys = dict1.keys() # step2: 遍历, 获取到 每个键. for key in keys: # key 就是字典的中的每个键, 根据键 获取值. value = dict1.get(key) # step3: 打印结果. print(key, value) print('-' * 30) # 上述格式简化版 for key in dict1.keys(): print(key, dict1.get(key)) print('-' * 30)
思路2:
根据键值对找键和值
# 思路2: 根据 键值对 找键和值. 理解为: 根据 结婚证 找丈夫和妻子. # step1: 获取所有的键值对. items = dict1.items() # step2: 遍历, 获取到每一组 键值对. for item in items: # item就是每组键值对的 元组形式, 即: (键, 值) # step3: 从item中获取到 键 和 值. key = item[0] value = item[1] # step4: 打印结果 print(key, value) print('-' * 30) # 合并版. for item in dict1.items(): print(item[0], item[1]) print('-' * 30) # 最终版, 实际开发写法, 加入拆包, 目前了解即可,后续详解. # item的格式为: (键, 值) for k, v in dict1.items(): print(k, v)
集合
定义
set1 = set()
set2 = {1, 2, 3, 4, 5}
set3 = {} # 这个的格式为字典
操作
增加操作
① add()方法:向集合中增加一个元素(单一)
② update()方法:向集合中增加序列类型的数据(字符串、列表、元组、字典)
# 增加单一元素 set1 = {10, 20, 3, 4, 5, 15} set1.add(40) set1.add(50) print(set1) # {50, 3, 4, 5, 20, 40, 10, 15} # 增加多个元素 set2 = {'刘备', '关羽'} list2 = ['张飞', '赵云'] set2.update(list2) print(set2) # {'刘备', '张飞', '关羽', '赵云'} # update()与字符串结合使用 set3 = {'刘备', '关羽'} set3.update('刘德华') print(set3) # {'德', '刘备', '关羽', '华', '刘'}
8.2.2删除操作
① remove()方法:删除集合中的指定数据,如果数据不存在则报错。
② discard()方法:删除集合中的指定数据,如果数据不存在也不会报错。
③ pop()方法:随机删除集合中的某个数据,并返回这个数据。
执行原理:系统自动对集合中的数据进行排序,排序后,pop()方法自动删除第一个元素
products = {'刘备', '张飞', '关羽', '赵云'} products.remove('刘备') print(products) # {'张飞', '关羽', '赵云'} products.remove('王二麻子') # 报错 products.discard('张飞') print(products) # {'赵云', '刘备', '关羽'} products.discard('王二麻子') # 不会报错 del_data = products.pop() print(del_data) # 某段时间内可能是一个值
8.2.3集合的查询操作
① in :判断某个元素是否在集合中,如果在,则返回True,否则返回False
② not in :判断某个元素不在集合中,如果不在,则返回True,否则返回False
set1 = {'刘备', '张飞', '关羽', '赵云'} # 判断某个元素是否在集合中 if '赵云' in set1: print("在") else: print('不在') # 遍历集合 for i in set1: print(i)
8.2.4集合的交并差
set1 = {'刘备', '张飞', '关羽', '赵云'} set2 = {'刘备', '孙策'} # 求交集 print(set1 & set2) # {'刘备'} # 求并集 print(set1 | set2) # {'刘备', '张飞', '关羽', '赵云', '孙策'} # 求差集 print(set1 - set2) # {'赵云', '张飞', '关羽'}