软件:PyCharm2023.2.5,Python3.12.4
目录
1. 输出
概述: 就是把 内容 打印到控制台上
格式: print('要输出的内容')
输出的几种方式:
(1) 直接打印变量值.
(2) 直接打印变量名.
(3) 同时打印多个变量值(或者变量名)
(4) 输出, 默认换行, 即end='\n', 手动指定end的值end='\t', 表示一个Tab的空格距离, end=''表示没有间距
(5) 格式化输出 -> %s代表字符串, %f代表小数, %d代表整数
(6) 格式化输出 -> f'内容 {变量名} 内容'
# 定义变量, 并赋值
name = '乔峰'
age = 38
weight = 120.5
# 打印结果
print(name, 'age', 188, end='\t') # 打印多个变量, 中间自动空出一个空格, 乔峰 age 188
print('aa', 'bb', 'cc') # aa bb cc
print('aa' + 'bb' + 'cc') # aabbcc
print() # 换行操作
# 格式化输出, 特殊: 百分号前需要加%, 引号前需要加转义符\
print('你好, 我叫: %s, 年龄: %d, 这是%%百分号, 这是\'引号' % (name, age)) # 你好, 我叫: 乔峰, 年龄: 38, 这是%百分号
print(f'你好, 我叫: {name}, 年龄: {age}, 这是%百分号') # 你好, 我叫: 乔峰, 年龄: 38, 这是%百分号
# 浮点型数据, 保留2位小数: %.2f :.2f
print('体重: %.2f' % weight) # 体重: 120.50
print(f'体重: {weight:.2f}') # 体重: 120.50
# 整数, 不够5位, 前面用 空格 补齐
print('年龄: %5d' % age) # 年龄: 38
print(f'年龄: {age:5d}') # 年龄: 38
# 整数, 不够5位, 前面用 0 补齐, 只能用空格或者0补齐, 其他的不能
print('年龄: %05d' % age) # 年龄: 00038
print(f'年龄: {age:05d}') # 年龄: 00038
2. 输入
Python中的输入指的是input()函数, 接收的数据默认都是字符串类型
格式: 变量名 = input('提示的内容')
# age = eval(input('请输入您的年龄: ')) # eval去引号
age = '18' # 为了便于测试, 这里赋值'18'
print(f'您的年龄是: {age}, age的类型是: {type(age)}') # 您的年龄是: 18, age的类型是: <class 'str'>
# 转成整型
age_int = int(age)
print(f'age_int的类型是: {type(age_int)}') # age_int的类型是: <class 'int'>
3. 注释与流程控制语句 控制跳转语句
3.1 注释
单行注释: # 注释内容
多行注释: 用三引号包裹即可, 可以是单引号, 也可以是双引号.
3.2 流程控制语句
概述: 指的是Python代码按照什么样的顺序来执行
分类:
(1) 顺序结构, 默认的结构, 代码按照从上往下 从左往右的顺序依次逐行执行
# 在数字运算中, 遵循运算优先级
print(5 + 5 - 3 + 2 * 3) # 13, 乘除的优先级比加减的优先级要高
(2) 分支结构, 指的是if语句, 在满足特定的条件下, 执行的代码
# if单分支
age = 17
if age >= 18:
print('哥已成年, 网吧可以去了!')
# if分支结构
if age >= 18:
print('哥已成年, 网吧可以去了!')
else:
print()
# if多分支 测试值的时候, 测试3种值: 合法值, 边界值, 非法值
if age >= 55:
print('奖励: 游乐场通票一张')
elif age >= 35:
print('奖励: 自助餐一次')
elif age >= 18:
print('奖励: 练习题一套')
elif age >= 0:
print('奖励: 玩具自选1个')
else:
print('年龄不合法, 请重新录入')
# if嵌套
if age > 18:
print('滴, 刷卡成功, 请上车!')
seat = 12
if seat > 0:
print('有座位, 可以坐下!')
else:
print('无座位, 站一会儿吧!')
else:
print('滴, 刷卡失败, 无法上车, 可以跟车跑!')
(3) 循环结构, 指的是for, while语句, 在满足特定的条件下, 重复执行的.
其中for循环, 更适用于循环次数固定的情况; while循环, 更适用于循环次数不固定的情况
# while循环
i = 1
while i <= 5:
if i <= 3:
print('i不超过3. ')
print('hello world')
i += 1
# while循环嵌套
# 打印正三角形 5行
"""
* 第一行1个
** 第二行2个
*** 第三行3个
**** 第四行4个
***** 第五行5个
* ' '*4 '*'*(1+0*2)
*** ' '*3 '*'*(1+1*2)
***** ' '*2 '*'*(1+2*2)
******* ' '*1 '*'*(1+3*2)
********* ' '*0 '*'*(1+4*2)
"""
# 单个*打印
i = 1
while i <= 5:
j = 1
while j <= i:
print('*', end='')
j += 1
print()
i += 1
# 单行*打印
i = 0
while i <= 4:
print(' ' * (4 - i) + '*' * (1 + i * 2))
i += 1
# 99乘法表
i = 1
while i <= 9:
j = 1
while j <= i:
print(f'{i}*{j}={i * j}', end='\t')
j += 1
print()
i += 1
3.3 控制跳转语句
指的是break和continue两个关键字
break: 终止循环, 循环不再继续往下执行
continue: 结束本次循环, 开始下次循环
4. 变量及数据类型
4.1 变量
概述: 变量指的是variable, 用来临时存储数据的, 其数据值存储在内存中.
作用: 临时存储数据, 存储在内存中.
格式: 变量名 = 变量值
细节: Python是一门弱类型的语言, 对变量的数据类型没有限定的那么严格, 变量可以接收任意的值.
4.2 数据类型
概述: 用来表示 变量 的类型的
常用数据类型:
整型 (int, 表示所有的整数),
浮点型 (float, 表示所有的小数),
布尔型 (bool, 表示所有的布尔值, 结果只有两个 True和False),
字符串型 (str, 表示所有的字符串, 值可以单行, 可以多行, 多行要用三引号)
列表 list()
元组 tuple()
字典 dict()
# 演示各类型变量
a = 10
b = 10.3
c = True
d = 'hello'
e = "world"
f = '''
hello
python!
'''
# 打印上述变量值
print(a) # 10
print(b) # 10.3
print(c) # True
print(d) # hello
print(e) # world
print(f) # hello
# python!
# 打印上述的变量类型
print(type(a)) # <class 'int'>
print(type(b)) # <class 'float'>
print(type(c)) # <class 'bool'>
print(type(d)) # <class 'str'>
print(type(e)) # <class 'str'>
print(type(f)) # <class 'str'>
4.3 类型转换
格式: int(变量名 或者 值), float(), bool(), str()
# int(), 转成整型, 特殊: True => 1, False => 0
print(int(True), int(False)) # 1 0
print(int(10.9)) # 10, 直接转成int丢失精度, 直接去掉小数部分
# float(), 转成标准的浮点型, 不支持设置小数位数, 特殊: True => 1.0, False => 0.0
print(float('10.3'), float('10')) # 10.3 10.0
print(float(True), float(False)) # 1.0 0.0
# str(), 转成字符串
print(str(10.3), str(True)) # 10.3 True
# eval(), 去掉前后引号
name = 'Jam'
print(eval('name'), 'name') # Jam name
# print(eval('张三')) # 报错
5. 标识符和关键字
5.1 标识符
概述: Python中用来给类, 函数, 变量等起名字的规则和规范.
命名规则:
(1) 由数字, 字母, 下划线组成.
(2) 数字不能开头.
(3) 不能和Python中的关键字重名.
(4) 最好做到见名知意.
(5) Python是区分大小写的, 即: a 和 A不一样.
命名规范:
(1) 类: 遵循大驼峰命名法. 例如: HelloWorld
(2) 变量名: 遵循小驼峰命名法. 例如: helloWorld
(3) 函数名: 遵循 蛇形命名法, 例如: get_sum
5.2 关键字
概述: 指的是key word, Python中被赋予了特殊含义的单词
# 查看Python中所有的关键字
# 导包
import keyword
# 打印Python中的所有的关键字
print(keyword.kwlist)
6. 运算符和组包拆包
6.1 运算符
概述: 用来连接变量或者变量值的符号
表达式: 用运算符连接起来的式子, 用什么运算符连接, 就叫什么表达式
例如, a + b 叫算术表达式, a > b 叫比较(关系)表达式
分类:
算术运算符, +, -, *, /, //(取整), %(取余), **(幂)
赋值运算符, =
复合赋值运算符, +=, -=, *=, /=, //=, %=, **=
比较(关系)运算符, ==, !=, >, <, >=, <=
逻辑运算符, and or not
三元运算符(三元表达式)
# 赋值运算符
a, b = 10, 3
# 算术运算符
print(a + b, a - b, a * b, a / b) # 13 7 30 3.3333333333333335
print(a // b, a % b, a ** b) # 3 1 1000
# 复合赋值运算符
a += b # a = a + b = 13
a -= b # a = a - b = 10
a *= b # a = a * b = 30
a /= b # a = a / b = 10.0
a //= b # a = a // b = 3.0
a %= b # a = a % b = 0.0
a **= b # a = a ** b = 0.0
# 比较运算符
a, b = 10, 3
print(a == b, a != b, a > b, a >= b, a < b, a <= b) # False True True True False False
b1 = a == b
b2 = a = b
print(b1, b2, a, b) # False 3 3 3
# 逻辑运算符
print(True and True) # True
print(True and False) # False
print(False and False) # False
print(False and False) # False
print(True or True) # True
print(True or False) # True
print(False or True) # True
print(False or False) # False
print(not True) # False
print(not False) # True
print(not not not False) # True
# 三元表达式
a, b = 10, 3
max = a if a > b else b
6.2 组包拆包
组包: 把多个值 => 1个值的过程
拆包: 把1个值 => 多个值的过程, 针对于元组 列表 字典 集合 字符串有效, 如果针对于字典拆包, 只能获取键的数据
# 组包演示
s1 = 'ghijkl'
list1 = [1, 2, 3, 4, 5]
tuple1 = (1, 2, 3, 4, 5)
dict1 = {'a': 1, 'b': 2, 'c': 3}
set1 = {1, 2, 3, 4, 5}
# 拆包演示
a, b, c, d, e, f = s1 # g h i j k l
a, b, c, d, e = list1 # 1 2 3 4 5
a, b, c, d, e = tuple1 # 1 2 3 4 5
a, b, c, d, e = set1 # 1 2 3 4 5
a, b, c = dict1 # a b c 只能获取键
7. 容器类型
容器类型: 是Python中的一个名词, 表示可以同时存储多个元素的一种数据类型
常用的容器类型: 序列(字符串str, 列表list, 元组tuple), 映射(字典dict), 集合(集合set)
字符串(str): 一个不可变的字符序列, 支持索引 切片和遍历
元组(tuple): 一个不可变的有序集合, 一旦创建后其内容不可更改, 支持索引 切片和遍历
列表(list): 一个可变的有序集合, 可以包含任意类型的元素, 支持索引 切片和遍历
字典(dict): 一个可变的键值对集合, 支持通过键快速访问对应的值, 键必须是不可变的(如字符串、元组等), 值可以是任意类型
集合(set): 一个可变的无序集合, 不允许重复元素, 支持集合操作如并集 交集和差集
容器类型公共运算符:
+ 合并(拼接), 适用于: 字符串, 列表, 元组 限于同种容器类型
* 复制, 适用于: 字符串, 列表, 元组 限于同种容器类型
in 是否包含, 适用于: 字符串, 列表, 元组, 字典(只作用于键)
not in 是否不包含, 适用于: 字符串, 列表, 元组, 字典(只作用于键)
容器类型的公共方法:
len() 获取长度的
del 删除的
max() 最大值
min() 最小值
range(start, end, step) 生成指定区间范围的值, 包左不包右
enumerate() 生成列表元素的索引和值, 封装成元组形式(索引, 值), 需要遍历出结果, 直接打印的是地址值, 类型是<class 'enumerate'>, 默认索引是从0开始的, 可以指定起始索引
推导式: 也叫解析式, 根据特定的规则生成1个数据序列的操作, 支持循环嵌套, 以及条件筛选的动作
列表推导式: [...] 格式: [变量名 for 变量名 in ... if 条件 ...]
集合推导式: {...}
字典推导式: {...}
元组没有推导式, (...)叫生成器(Generator)
引用: python中存储变量是需要占用内存空间的, 为了更好的管理这些空间, 每块空间都有自己的地址值
格式: id(变量名 或者 变量值), 可以查看变量在内存中的地址值
可变类型和不可变类型的划分依据: 在不改变地址值的情况下, 其元素值是否可以发生改变, 可以=
可变类型, 不可以=>不可变类型
可变类型: 列表, 字典, 集合
不可变类型: 字符串, 元组, 浮点型, 布尔型, 整型
# 列表推导式
print([i for i in range(10) if i % 2 == 0]) # [0, 2, 4, 6, 8]
print([(i, j) for i in range(1, 3) for j in range(3)]) # [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
# 字典推导式
print({i: i ** 2 for i in range(1, 6)}) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
list1 = ['name', 'age', 'gender']
list2 = ['Tom', 20, 'man', 50]
# 这里的长度只能是长度最小的列表
print({list1[i]: list2[i] for i in range(len(list1))}) # {'name': 'Tom', 'age': 20, 'gender': 'man'}
7.1 字符串str
下标/索引:
正向索引(从左往右或从前往后), 默认从0开始;
反向索引(从右往左或从后往前), 默认从-1开始;
获取字符串的某个指定字符: 字符串变量名[索引值]
遍历字符串: 通过索引方式
获取字符串长度: len()
切片: 字符串变量名[起始索引:结束索引:步长]
起始索引默认是0(正向索引时), -1(反向索引时)
结束索引默认是 字符串长度-1(正向索引时), 字符串长度的负数形式(逆向索引)
步长默认是1
如果起始索引到结束索引的方向 和 步长的方向不一致, 则获取不到数据
切片特殊写法: 字符串变量名[::-1], 表示字符串反转
字符串函数: 操作字符串变量或者字符串的一些函数
查找类:
字符串变量名.find(要查找的子串, 起始索引, 结束索引) 找子串在字符串中第一次出现的位置, 找到就返回子串的起始索引, 找不到就返回-1
字符串变量名.index(要查找的子串, 起始索引, 结束索引) 找子串在字符串中第一次出现的位置, 找到就返回子串的起始索引, 找不到就报错
字符串变量名.rfind(要查找的子串, 起始索引, 结束索引) 找子串在字符串中最后一次出现的位置, 找到就返回子串的起始索引, 找不到就返回-1
字符串变量名.rindex(要查找的子串, 起始索引, 结束索引) 找子串在字符串中最后一次出现的位置, 找到就返回子串的起始索引, 找不到就报错
替换和切割类:
字符串变量名.replace(旧子串, 新子串, 替换次数) 用新的替换旧的, 且可以设置替换几个(如超出真实旧子串个数, 则以实际为准)
字符串变量名.split(分隔符, 切割次数) 按照分隔符切割, 且可以设置切割次数(如超出真实切割次数, 则以实际为准)
注: 因为字符串属于不可变数据类型, 所以上述函数操作字符串后, 会返回1个新的结果, 即旧字符串不变
# 字符串正向索引, 反向索引
str1 = 'hellopython'
"""
h e l l o p y t h o n
0 1 2 3 4 5 6 7 8 9 10
-11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1
"""
# 字符串索引对应的值, 字符串的长度
print(str1[0], len(str1)) # h 11
# 访问字符串中每个字符
print(list(i for i in str1)) # ['h', 'e', 'l', 'l', 'o', 'p', 'y', 't', 'h', 'o', 'n']
for i in str1:
print(i)
# 字符串切片
print(str1[::], str1[::-1]) # hellopython nohtypolleh
print(str1[:2:-2]) # nhyo
print(str1[4:-10], str1[1:-4:-1]) # 无数据, 顺序不一致
# 字符串替换
s1 = "hello python hello world hello sql"
s2 = s1.replace('hello', 'hei') # 如果不写个数, 会一次性替换所有
s3 = s1.replace('hello', 'hei', 100) # 替换次数超过真实个数时, 则以实际为准
print(s2) # hei python hei world hei sql
print(s3) # hei python hei world hei sql
# 字符串切割
s4 = s1.split(' ') # 切割后, 获取的是一个字符串形式的列表
s5 = s1.split(' ', 100) # 切割个数超过真实个数, 以实际为准
print(s4) # ['hello', 'python', 'hello', 'world', 'hello', 'sql']
print(s5) # ['hello', 'python', 'hello', 'world', 'hello', 'sql']
# 扩展: in, not in判断指定字符是否在字符串中
print('python' in s1) # True
print('Python' not in s1) # True
练习题
# 练习题1: 找小串在大串中出现的次数
max_str = "hello python hello world hello sql"
min_str = 'hello'
# 思路1: 循环, 这里max_str是变动的, 一般用while True循环, 对于不变动的一般用for循环
# 定义变量, 用于小串出现次数的计数
count = 0
while True:
# 找小串第一次出现的位置
idx = max_str.find('hello')
# 如果idx为-1, 说明没有找到, 此时可以结束循环
if idx == -1:
break
# 计数加一
count += 1
# max_str切片, 跳过小串, 重新赋值
max_str = max_str[idx + len(min_str):]
# 打印结果
print(f'小串 {min_str} 在大串中出现的次数为 {count}次')
# 思路2: 小串的长度 = (大串的长度 - 新串的长度) / 小串的长度
max_str = "hello python hello world hello sql"
min_str = 'hello'
# 替换小串为''
new_str = max_str.replace(min_str, '')
# 计算减去了多少个小串
count = (len(max_str) - len(new_str)) // len(min_str) # /得到3.0, 改用//取整得到3
# 打印结果
print(f'小串 {min_str} 在大串中出现的次数为 {count}次')
# 思路3: 容器类型有count()函数, 容器类型有字符串str, 列表list, 元组tuple, 字典dict, 集合set
count = max_str.count(min_str)
print(f'小串 {min_str} 在大串中出现的次数为 {count}次')
# 练习题2: 交换两个变量值
a = 10
b = 3
# 思路1: 中间变量, 即临时变量
c = a
a = b
b = c
print(a, b) # 3 10
# 思路2: 直接交换, 拆包
a, b = b, a
print(a, b) # 10 3
# 思路3: 数值加减, 算术运算符
a = a + b # a:a+b b:b
b = a - b # a:a+b b:a
a = a - b # a:b b:a
print(a, b) # 3 10
# 思路4: 位运算符(一个数字被同一个数字 位移或两次, 该数字值不变
a = a^b # a:a^b b:b
b = a^b # a:a^b b:a^b^b=a
a = a^b # a:a^b^a=b b:a
print(a, b) # 10 3
7.2 列表list
可变类型: 其元素值可以直接修改
格式:
list = [值1, 值2...]
list = [] # 定义空列表, 推荐这种写法
list = list() # 定义空列表
索引: 也叫下标, 脚标, index, 默认从0开始(正向索引) -1(逆向索引)
切片: 支持
增:
列表名.append(任意变量即可) 往列表的末尾追加元素
列表名.extend(必须是容器变量) 把容器类型中的每个变量都添加到列表中
列表名.insert(索引, 元素) 往列表的指定位置插入元素
查:
列表名.index(元素, 起始索引, 结束索引) 去列表中查找指定的元素(第一次出现的位置), 找不到报错
列表名.count(元素) 计数
变量名或者元素值 in 列表名 是否在
变量名或者元素值 not in 列表名 是否不在
删:
列表名.pop(索引) 删除指定索引位置的元素, 并返回被删除的元素
列表名.remove(元素) 删除指定元素, 删除第一个找到的元素
del 列表名[索引] 删除指定索引位置的元素
del 列表名 从内存中删除整个列表, 相当于该列表从未定义
列表名.clear() 清空列表, 得到1个空列表, 类似于list1 = []
改:
列表名[索引] = 值
列表名.reverse() 反转列表元素内容
列表名.sort(key=None, reverse=False) 列表元素排序, key可以指定排序规则, 例如lambda word: len(word)按字符串长度排序/word[1]按字符串第2个元素排序, reverse表示升序还是降序, 默认是False(升序)
面试题: append() 和 extend()的区别:
区别1: 参数要求不同.
append(): 可以传入 任意变量.
extend(): 必须传入 容器类型.
区别2: 作用不同.
append(): 把元素追加到末尾, 默认是 当做1个整体 来添加的.
extend(): 把容器类型的每个元素, 逐个添加进来, 底层有遍历的动作.
# 列表可以同时存储多个不同类型的值, 但是不推荐, 因为不好管理
list1 = [10, 20, 10.3, True, False, 'abc']
print(list1[0], list1[-1]) # 10 abc
# 遍历列表
# 方式1: 直接获取列表的每个元素值
for i in range(len(list1)):
print(i)
# 方式2: 通过索引的方式获取列表的元素值
# for循环
for i in range(len(list1)):
print(list1[i])
# while循环
i = 0
while i < len(list1):
print(list1[i])
i += 1
# 列表的嵌套
list2 = [[10, 20, 30], [40, 50], [60, 70, 80, 90]]
# 索引
print(list2[0][1]) # 20
# 切片, 对原列表不作改变
print(list2[0:2]) # [[10, 20, 30], [40, 50]]
# 列表的增删改查
list3 = ['a', 'b', 'c']
# 增:
# append任意变量
list3.append(10) # ['a', 'b', 'c', 10]
# extend必须是容器变量
list3.extend('d') # ['a', 'b', 'c', 10, 'd']
# insert往指定位置的 前面 插入元素
list3.insert(-1, 'e') # ['a', 'b', 'c', 10, 'e', 'd']
# 查:
# index返回第一次出现的位置, 找不到就报错
print(list3.index(10)) # 3
# count计数
print(list3.count('e')) # 3
# in是否在
print('q' in list3) # False
# not in是否不在
print(10 not in list3) # False
# 删:
# pop删除指定位置, 并返回删除的元素, 找不到就IndexError, 索引越界错误
print(list3.pop(3)) # 10
# remove删除第一个找到的元素, 找不到就ValueError, 元素值不在列表中
list3.remove('e') # ['a', 'b', 'c', 'd']
# del删除索引位置的元素
del list3[0] # ['b', 'c', 'd']
del(list3[0]) # ['c', 'd']
# clear清空列表, 得到一个空列表
list3.clear() # []
# 改:
# 直接改
list3 = ['a', 'b', 'c']
list3[0] = 'd' # ['d', 'b', 'c']
# reverse反转
list3.reverse() # ['c', 'b', 'd']
# sort默认reverse为: False升序
list3.sort(reverse=True) # ['d', 'c', 'b']
7.3 元组
格式:
uple1 = (值1, 值2, 值3...)
tuple2 = tuple()
tuple3 = ()
tuple4 = (10, ) 如果元组只有1个元素, 则该元素后必须加逗号
tuple5 = (10) 如果不加逗号, 那就说明它就是1个该类型的变量 <class 'int'>
下标和切片: 支持
常用函数: index() count() len()
# 定义元组
tuple1 = (10, 20, 30, 40, 50)
# 切片, 切片后对原有元组不作修改
print(tuple1[2:4]) # (30, 40)
# index第一次出现的位置, 找不到就报错ValueError
print(tuple1.index(20)) # 1
# count计数
print(tuple1.count(10)) # 1
# 元组嵌套列表
tuple2 = ([10, 20], [30, 40, 50], [60])
tuple2[0][1] = 1 # ([10, 1], [30, 40, 50], [60])
7.4 字典
格式:
dict1 = {键:值, 键:值, ...}
dict2 = dict{}
dict3 = {}
特点: 键具有唯一性, 值可以重复
增/改: 字典名[键] = 值, 键存在就修改, 不存在就新增
删: del clear()
查: get(键名, 默认值) keys() values() items()
# 定义字典
dict1 = {'name':'张三', 'age':23, 'gender':'male'}
dict2 = {10, 20, 30, 40} # 这个不是字典, 而是集合
print(dict2) # {40, 10, 20, 30}, 集合set内的元素排列顺序不固定
print(type(dict2)) # <class 'set'>
# in, not in运算符, 只作用于键
print('张三' in dict1) # False
# 增
dict1['weight'] = 50
# 改
dict1['name'] = 'Jam'
# 删, 根据键删除该键值对, 不存在就报错
del dict1['name']
# 查, 根据键获取其对应的值, 如果不存在就返回默认值, 默认值不写则为None
print(dict1['gender']) # male, key访问, 字典[key]的方式获取值, 如果key不存在则报错
print(dict1.get('gender', 'male')) # male, get方法访问, 不会报错
print(dict1.keys()) # dict_keys(['age', 'gender', 'weight'])
print(dict1.values()) # dict_values([23, 'male', 50])
print(dict1.items()) # dict_items([('age', 23), ('gender', 'male'), ('weight', 50)])
# 遍历字典
# 方式1: 根据键 获取 对应的值
for key in dict1.keys():
print(key, dict1.get(key))
# 方式2: 根据键值对 获取 键和值
for item in dict1.items():
print(item[0], item[1])
# ==> 最终实际开发中, 加入拆包
for k, v in dict1.items():
print(k, v)
练习题
# 练习题1:删除指定的元素
# 方法1: 根据索引删除, 正向遍历
words_list = ['bb', 'aa', 'cc', 'cc', 'cc', 'dd', 'cc']
i = 0
while i < len(words_list):
if words_list[i] == 'cc':
words_list.pop(i)
# 走到这里, 说明已经删除了一个元素, 元素整体前移, 下标需要重新赋值
i -= 1
# 走到这里, 说明元素判断完毕, 无论是否删除, 都需要继续判断下个元素了
i += 1
print(words_list) # ['bb', 'aa', 'dd']
# 方法2: 根据索引删除, 逆向遍历
words_list = ['bb', 'aa', 'cc', 'cc', 'cc', 'dd', 'cc']
i = len(words_list) - 1
while i >= 0:
if words_list[i] == 'cc':
words_list.pop(i)
# 走到这里, 说明元素判断完毕, 无论是否删除, 都需要继续判断前个元素了
i -= 1
print(words_list) # ['bb', 'aa', 'dd']
# 方法3: 列表推导式
words_list = ['bb', 'aa', 'cc', 'cc', 'cc', 'dd', 'cc']
words_list = [word for word in words_list if word != 'cc']
print(words_list) # ['bb', 'aa', 'dd']
# 方法4: 过滤器filter(过滤规则, 要操作的容器对象)
words_list = ['bb', 'aa', 'cc', 'cc', 'cc', 'dd', 'cc']
words_list =list(filter(lambda word: word != 'cc', words_list))
print(words_list) # ['bb', 'aa', 'dd']
# 方法5: 深浅拷贝: 列表名[::1] 底层会随着列表元素的变化而动态变化
words_list = ['bb', 'aa', 'cc', 'cc', 'cc', 'dd', 'cc']
for word in words_list[::1]:
if word == 'cc':
words_list.remove(word)
print(words_list) # ['bb', 'aa', 'dd']
# 练习题2: 统计每个字符出现的次数: # 空间复杂度O(n2), 因为需要每次都对比一次
s = 'abfdjszgsruyzbfvkzsdureaig'
# 方式1: 遍历
char_count_dict = {}
for char in s:
# 字典名.get(键, 默认值), 根据键获取对应的值, 如果没有该键, 赋默认值0
# 对于每个字符, 对应的键的值都加1
char_count_dict[char] = char_count_dict.get(char, 0) + 1
# 方式2: 字典推导式
char_count_dict = {char: s.count(char) for char in s}
# 打印结果
for k, v in char_count_dict.items():
print(f'{k}({v})', end='')
# 练习题3: 统计大写小写数字字符的次数
s = 'zbdAS12354DFvHYjhe2546sbKD'
big_count, small_count, num_count = 0, 0, 0
for char in s:
# 方式1: Python独有写法
if 'A' <= char <= 'Z':
big_count += 1
if 'a' <= char <= 'z':
small_count += 1
if '0' <= char <= '9':
num_count += 1
print(f'大写字母字符的个数为: {big_count}, 小写字母字符的个数为: {small_count}, 数字字符的个数为: {num_count}')
big_count, small_count, num_count = 0, 0, 0
for char in s:
# 方式2: Python函数
if char.isupper():
big_count += 1
if char.islower():
small_count += 1
if char.isdigit():
num_count += 1
# 打印结果
print(f'大写字母字符的个数为: {big_count}, 小写字母字符的个数为: {small_count}, 数字字符的个数为: {num_count}')
# 练习题4: 约瑟夫环
"""
10个人围成一个圈, 从1开始数数字, 只要数到3或3的倍数, 就要被杀掉, 直至剩下最后一个人, 他的位置就是幸运数字
"""
num_list = [i for i in range(1, 11)] # 生成位置序列
# 方式1: 循环
count = 0 # 表示每个人所数的数字
i = 0 # 表示每个人自己的位置
while len(num_list) != 1:
# 每次循环, count加一, 判断是否为3的倍数
count += 1
if count % 3 == 0:
num_list.pop(i)
# 如果是3的倍数, 杀掉这个人之后, 每个人自己的位置向前移动1
i -= 1
# 判断完之后, 轮到下一个人判断
i += 1
# 如果本轮最后一个人的位置, 等于目前队伍的长度, 则重新赋值, 开始下一轮判断
if i == len(num_list):
i = 0
# 打印结果
print(f'幸运数字是: {num_list[0]}')
# 方式2: 公式完成
num_list = [i for i in range(1, 11)] # 生成位置序列
i = 0
while len(num_list) != 1:
i = (i + 2) % len(num_list) # %取余, 两个人之后就是第三个人, 如果i超过队列长度, 取余获得下一个被杀的位置
num_list.pop(i)
# 打印结果
print(f'幸运数字是: {num_list[0]}')
7.5 集合
格式: set1 = {值1, 值2, 值3...}
set2 = set()
set3 = {}
特点: 无序(元素的存 取顺序不一致), 唯一
应用场景: 去重
# 去重
list1 = ['aa', 'bb', 'cc', 'cc', 'cc', 'dd', 'bb', 'cc']
print(list(set(list1)))
关于包左包右
import random
print(random.randint(1, 2)) # 包左包右
print(list(range(1, 6))) # range(a, b)包左不包右
print('abcdefghijklmnopqrstuvw '[1:5]) # 包左不包右
8. 函数
概述: 函数也叫方法, Function(函数, 功能), Method(方法)表示, 函数 = 把具有独立功能的代码封装到一起, 使其成为具有特殊功能的代码集
抽取函数快捷键: ctrl + alt + m
好处: 提到代码的复用性, 模块化编程
格式:
def 函数名(形参1, 形参2...): # 函数名最好做到见名知意
三引号 说明文档 三引号 # 函数的说明文档, 函数内部的第一行, 用三引号包裹
函数体
return 具体的返回值 # 作用1(主职): 结束函数的, 作用2(副职): 可以返回函数执行结果
调用格式: 写函数名(), 传入实参, 接收返回值
根据参数和返回值的不同, 主要分为四种写法: 无参无返回值, 有参无返回值, 无参有返回值, 有参有返回值
参数的分类:
(1) 实参 位置参数, 实参和形参的个数, 对应的顺序(位置)都要相同
(2) 实参 关键字参数, 必须通过形参名=值的形式传递实参, 实参和形参的个数必须保持一致, 对顺序无要求; 如果写实参的时候, 既有位置参数, 又有关键字参数, 则位置参数必须在关键字参数的前边, 关键字参数之间依旧没有顺序要求
(3) 形参 普通参数, 即命名参数,
(4) 形参 缺省参数, 也叫默认参数, 作用于形参列表, 给形参赋一个初始值, 如果没有这个参数传递, 就用默认值; 形参列表中如果有缺省参数, 必须放在参数列表最后; 大致顺序: 普通参数 => 缺省参数 => 不定长参数
(5) 形参 不定长参数(*args, **kwargs), *args, 可以接收任意多个位置参数, 并封装成元组; **kwargs, 可以接收任意多个关键字参数, 并封装成字典
形参是不可变类型, 形参的改变对实参没有任何影响
形参是可变类型, 形参的改变直接影响实参
当一个函数有返回值的时候, 这个函数可以作为参数传入另一个函数中
当一个函数返回多个值(返回1个结果), 会把多个值封装成1个元组进行返回
函数的嵌套调用: 指的是在一个函数中, 调用另一个函数, 根据入栈的顺序, 进行执行
细节: 函数的功能越单一越好, 最好1个函数只做1件事
变量的作用域: 指的是变量的作用范围, 即变量在哪里能用, 在哪里不能用
局部变量: 定义到函数的形参列表, 或者函数内的变量,
生命周期: 随着函数的调用而存在, 函数的调用完毕而消失
全局变量: 定义到函数外的变量, 或者global修饰的变量, 在当前模块中的函数, 都可以使用,
生命周期: 随着模块的加载而存在, 模块的卸载而消失
global: 被修饰的变量 => 全局变量, 可以实现定义在函数内的变量, 在函数外使用
匿名函数: 没有名字的函数, 也叫Lambda表达式 Lambda函数
格式: lambda 形参列表: 函数体
适用场景: 只适用于简单的业务场景, 函数体只有一行代码, 且有返回值的这种函数
# 演示 普通参数 + 缺省参数 + 不定长参数, 接收所有的位置参数 = 关键字参数
# 普通参数 缺省参数 不定长参数
def user_info(a, b, c=10, d=20, e='AI30期', *args, **kwargs):
print(f'a: {a}, b: {b}, c: {c}, d: {d}, e: {e}') # a: 1, b: 2, c: 3, d: 4, e: 5
print(f'args: {args}') # args: (6, 7, 8, 9)
print(f'kwargs: {kwargs}') # kwargs: {'name': '李四', 'gender': '女'}
if __name__ == '__main__':
user_info(1, 2, 3, 4, 5, 6, 7, 8, 9, name='李四', gender='女')
# 形参是不可变类型, 形参的改变对实参没有任何影响; 形参是可变类型, 形参的改变直接改变实参
def change1(a, b):
a = 200
b[1] = 1
if __name__ == '__main__':
change1(100, [2, 3, 4]) # 200 [2, 1, 4]
# 匿名函数
def get_sum(a, b):
return a + b
if __name__ == '__main__':
get_sum(10, 3) # 13
get_sum1 = lambda a, b: a + b
get_sum1(10, 3) # 13
# 匿名函数作为方法的实参进行传递
def my_calculate(a, b, func):
return func(a, b)
if __name__ == '__main__':
my_calculate(10, 3, lambda a, b: a * b) # 30
练习题
# 练习题1: 扑克牌发牌
# 定义造牌函数
def buy_pokers():
"""
定义造牌函数, 造出54张扑克牌
:return: 扑克牌的字典, 以及对应的索引序列
"""
poker_color = ['♠️', '♥️', '♦️', '♣️']
poker_num = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A', '2']
poker = []
for num in poker_num:
for col in poker_color:
col_num = col + num
poker.append(col_num)
poker.extend(['🃁', '🃏'])
pokers = {item[0]:item[1] for item in enumerate(poker)}
poker_list = list(pokers.keys())
return pokers, poker_list
# 定义洗牌函数
def shuffle_poker_list(poker_list):
"""
扑克牌进行洗牌, 即序列随机置换
:param poker_list:进行随机置换的序列
:return: 随机置换后的序列
"""
import random
random.shuffle(poker_list)
return poker_list
if __name__ == '__main__':
pokers, poker_list = buy_pokers()
print(pokers)
print(poker_list)
poker_list = shuffle_poker_list(poker_list)
print(poker_list)