python简介
python优点
- 简单 语法简单 代码格式简单
- 开源 开放源代码(底层源代码c) 所有的开发者都可以对编程语言提出修改意见
- 应用广泛 什么都能做,什么都不精
python缺点
- 执行效率特别低 pyqt(qt) numpy(c语言)
- 胶水语言 (可以调用很多语言写的功能)
TIOBE编程语言排行榜
TIOBE 2021 6
python版本
python2
python3 python3用的比较多
anaconda
虚拟环境
特点
- 解释型
- 动态数据类型
- 面向对象
学习路径
python解释器
编译型和解释型
计算机只能识别二进制的机器码 0101
编译型
一次性把代码翻译成二进制的机器码 ,生成可执行程序或库
编译器
c/c++
运行速度快
解释型
读取一段,解释执行一段
解释器
python js
运行速度慢
常见的Python解释器
- CPython 官方解释器 c语言实现的(安装的就是这个)
- IPython 交互式的(内核CPython) 360极速浏览器
- PyPy JIT(just in time)技术 行动态编译
- Jython 把Python代码编译成Java字节码执行
- IronPython 把Python代码编译成.Net的字节码
python和pycharm区别
python解释器
解释器,程序运行的时候需要解释器把代码翻译成二进制的机器码
pycharm
集成开发环境
简化操作
debug调试程序
注释
代码解释说明,不会参与代码执行
- 开发新的项目
- 项目迭代开发 熟悉别人写的代码
单行注释
# 注释内容
print('hello')
快捷键 Ctrl+/
多行注释
'''
注释内容
'''
"""
注释内容
"""
变量
变量
给数据存储的内存空间起名字 可以直接使用变量名称操作内存空间
作用
申请空间,存储数据
变量的注意点
- 变量命名
- 变量指向空间的用途 数据类型
18a
a = ‘zhangsan’
命名规则
- 由数字、字⺟、下划线组成
- 不能数字开头
- 不能使⽤内置关键字
- 严格区分⼤⼩写
获取python关键字
import keyword
result = keyword.kwlist
print(result)
命名规范
见名知义
实现功能->设计模式(简单-复杂)
下划线命名法:
大驼峰:
小驼峰:
zhang_san = '张三'
ZhangSan = '张三'
zhangSan = '张三'
变量定义
python属于弱类型语言 定义变量的时候不需要指定的变量类型
# 变量名 = 变量值
my_name = '张三'
# 访问内存空间
print(my_name)
# 修改空间对应的数据
my_name = '李四'
如果不希望变量后续进行修改,可以把变量名全部变成大写
# 定义变量保存圆的半径和圆周率
radius = 12
# pi应该固定值 不希望后续进行修改
PI = 3.14
使用ctrl+alt+l 可以使样式规范化
数据类型
基本类型
数据类型 | 描述 |
---|---|
int | 整型 |
float | 浮点型 |
bool(True 1 False 0) | 布尔型 |
高级变量类型
数据类型 | 描述 |
---|---|
str | 字符串 |
list | 列表 |
tuple | 元组 |
set | 集合 |
dict | 字典 |
获取数据类型
type(数据/变量名)
python数据类型可以修改
a = 10
print(type(a))
a = 20
print(type(a))
a = '张三'
print(type(a))
输入和输出
输出和输入是用户和程序交互方式
输出
程序执行结果输出到控制台
格式化符号:组合输出的时候会用到 可以根据变量生成新的字符串
%s: 字符串
%d: 整型 %06d 不足6位以0补齐
%f: 浮点类型 %.2f 保存两位小数
多个变量输出
print('我的名字是%s,明年%d岁了' % (name, age + 1))
f格式化输出(支持python3.6及以上版本)
print(f'我的名字是{name},今年{age}岁了')
转义字符
\n:换行
\t:制表符 4个空格 Tab
print结束符
print('hello',end=' ') #''中可以写转义符,可以写其他的符号用于间隔,如...
bug
常见bug
- 命名错误 NameError
- 缩进错误 IndentationError
- 语法错误 SyntaxError
Debug工具使用
debug工具使PyCharm IDE中集成的用来调试程序的工具。
- 打断点
- Debug调试
多断点时
对于多个断点如果想跳到下一个断点可以点三角标(resume program)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ISwfAfQN-1628652111864)(E:\接受资料\python基础\day01-python环境搭建与输出\img\2.png)]
在debug中,如果需要检查一个很长的式子中的运算情况,可以选中检查的内容右键选择add to watches
python
变量
输入输出
流程控制语句
if语句
循环语句
高级变量类型
函数 函数式变成
文件I/O
输入
password = input('请输入您的密码:')
print(f'您输入的密码是{password}')
print(type(password))
- 程序停在input
- input可以有输出提示
- 需要在控制台输入之后回车继续执行
特点
- 遇到input,等待用户输入
- 接受input存变量
- input接收到的数据类型都是字符串
数据类型转换
int float str
# -------------- 转换成int类型 -------------- #
# s = input()
# print(s)
# int
# i = int(s)
# print(type(i))
# 30 '30'
# print(int('30'))
# print(int('1.1232')) 字符串类型里的浮点型不可以转换只能是整型
# -------------- float -------------- #
# f = float(1) 整型可以转换成浮点型的
# print(f) -- 0.1
# i = int(1.234) 浮点型可以转换成整型(与上面的情况不一样)
# print(i)
# -------------- str -------------- #
# print(str(10)) 整型转字符串
# print(str(10.5)) 浮点型转字符串
# print(str([10,20,30])) 列表转字符串
# 任何类型都可以转换成字符串类型
eval
用来执行一个字符串表达式,并返回表达式的值
a = 10
a>30
s1 = eval('[1,2,3]') #返回列表
s1 = eval('10+20') #返回30
a = 10
#a+20
s1 = eval('a+20')
print(s1) #报错,a未定义
print(type(s1))
bool
在python中任何类型都可以作为bool类型,
s = input('请输入True或False')
#对于字符串来说,若使用bool进行布尔类型的转换的时候,只要字符串不是空就代表True,
result = bool(s)
#若想输入False打印出False,要用eval转换
result = eval(s)
print(type(result)) #bool类型
print(result)
运算符
在python中字符串是不可以和数值类型的进行加,但是可以乘
result = 'hello' * 10 #可以,代表将字符串重复10次 result = 'hello' + 10 #不可以
算术运算符
/: 10/2 得出浮点类型的数据5.0
//:整除 10//3
%:取余/取模 10%3
**: 指数 2**3
():提高运算的优先级
赋值运算符
=:
# 单变量赋值
a = 10
# 多变量赋值
a,b = 10,20
# 多变量赋相同的值
a=b=10
- 实现功能 2.优化程序 代码简化 执行效率优化
复合赋值运算符
把算术运算符和赋值运算符复合使用
算术运算符赋值运算符
a = 10
a += 1 # a = a+1
# a *= 1+2 a = a*(1+2)
# 自增自减法 a++ ++a
注意:
复合赋值运算符 先计算等号右边表达式 再和左边表达式计算
比较运算符(数字比较 返回bool)
=:赋值运算符
==:是否相等
'hello' == 'world'
逻辑运算符(bool逻辑运算 返回bool)
条件判断
逻辑与: and 左右两边都满足返回True
逻辑或: or 只要有一个满足 返回True
逻辑非: not 取反
# & and <=> && and相当于java中的&&,若左边已经是false就不会再计算右边的
# | or <=> || 同上
and 左边不满足 右边不会执行
or 左边满足 右边不会执行
数字的逻辑运算符
python所有的类型都可以作为True和False的判断
#在很多语言中0为False,非0为True
result = 10 and 30 #如果两个都不是0,返回最后一个数据,在这里是30
result = 0 and 10 #如果有一个是0,就返回0,无论0是在前面还后面
result = 10 and 0
result = 10 or 0 #如果有一个是0,无论在前面还是后面都是返回True的数据
result = 0 or 10
result = 20 or 10 #如果两个都不是0,返回第一个
result = not 10 #返回False
result = not 0 #返回True
s = ''
result = not s #返回True
流程控制语句
if
while
for
控制程序执行流程
条件语句:满足一定条件执行特定的代码
循环语句:一段代码循环执行
条件控制语句if
if代码格式
代码1
if 条件:
条件满足执行代码
条件满足执行代码
代码2
if else
if 条件:
满足条件执行的代码
else:
不满足条件执行的代码
if elif else
if 条件1:
满足条件1执行的代码
elif 条件2:
满足条件2执行的代码
elif 条件3:
满足条件3执行的代码
....
else:
不满足条件执行的代码
if语句只要有分枝满足条件,执行这个分枝 后续分枝不会判断也不会执行
因此可以按照返回的顺序进行优化,如下
if score>=90:
print('优秀')
# 如果这个分数在75(包含75)和90之间,那么输出“良好”;
elif score>=75:# <90
print('良好')
# 如果这个分数在60(包含60 60-75)以上,那么输出“及格”;
elif score>=60:# <75
print('及格')
else:# <60
print('不及格')
实际项目开发中,尽量不用嵌套
python js
随机数
import random
random.randint()
三目运算符
简化if语句
通过变量接受三母运算符的结果(正常的if判断语句是不可以接收if的结果的)
c = 结果1 if 条件2 else 结果2
循环
作用
代码高效重复执行
分类
while、for
循环控制语句while
while语法结构
while 条件:
满足条件执行的代码
一定要记得增加计数器,避免死循环
死循环
循环一直执行不会停下来
图形化开发( pygame pyqt) --需要通过死循环让图形化界不会停下来
服务器程序 --需要服务器一直运行
while True:
pass
break和continue(循环里面才能用)
break:停止循环
continue:停止当前循环继续下一次循环
嵌套
代码习惯
- 分析需求
- 写流程步骤
- 填充代码
- 简洁
- 适用性 一些通用的变量要定义出来,在流程处理的时候,尽量用定义好的变量找得内在关系,进行运算得出隐藏的条件。如下的打印
'''
*
* *
* * *
* * * *
* * * * *
* * * *
* * *
* *
*
分析:
9行半个菱形
1. 外层循环控制行数
2. 内层循环控制如何打印
'''
num = 9
# 1. 外层循环控制行数
row = 1
while row < num + 1:
# 中间行号,中间行的星号个数
centerLine = num // 2 + 1
# 当前行星号,abs是绝对值
curStar = centerLine - abs(centerLine - row)
# 知道这一行星号个数
i = 0
while i < curStar:
print('*',end='')
i += 1
# 一行打印完成
print()
# 2. 内层循环控制如何打印
row += 1
循环控制语句for
for循环语法
for 临时变量 in 序列:
循环代码
int float bool
str list set dict range
for循环作用
遍历容器数据类型,字符串 列表 元组 集合 字典 区间range
str list tuple set dict
while循环可以设定循环的次数,如从1循环到100
for循环次数跟元素个数相关
for案例
str1 = 'itheima'
for i in str1:
print(i)
相当于其它语言的高级for循环,如java的foreach循环
break和continue
break
遇到break循环停止
str1 = 'itheima'
for i in str1:
# 当某些条件成立退出循环 -- break:条件 i取到字符e
if i == 'e':
break
print(i)
continue
停止当前循环,继续下一次循环
str1 = 'itheima'
for i in str1:
# 当某些条件成立退出循环 -- continue:条件 i取到字符e
if i == 'e':
continue
print(i)
连续
1.打印字符串’hello world’中除了’w’之外的每一个元素
s = 'hello world'
for ele in s:
# 遇到w 跳过去
if ele=='w':
continue
print(ele)
2.打印字符串’hello world’中第一个’o’出现之前(不包含第一个’o’)的所有元素
s = 'hello world'
for ele in s:
if ele=='o':
break
print(ele)
3.打印字符串’hello world’中第三个’l’出现之前(不包含第三个’l’)的所有元素
c = 0
for ele in s:
if ele == 'l':
c+=1
if c==3:
break
print(ele)
循环结合else
循环结合else语法结构
while 条件:
条件满足执行的代码
else:
else里面的代码
else中的代码是在循环正常结束之后执行
特点
循环中执行break,else不会执行
作用
在循环正常结束的前提下才能执行else,使循环的内容与else之间建立了一种依赖关系,而不是普通的按顺序执行,不执行循环后面的代码也能执行
抽签(随机数1-9)3次,如果抽到6说明很幸运,媳妇原谅,如果三次都没有抽中6就跪搓衣板
import random
# 1. 循环三次
i = 0
while i < 3:
# 2. 每一次循环抽签(获取1-9随机数)
num = random.randint(1, 9)
print(f'抽签结果:{num}')
# 抽中, 原谅 停止抽签
if num==6:
print('很幸运,媳妇原谅')
break
i += 1
else:
# 没有抽中 跪搓衣板
print('跪搓衣板')
普通实现
import random
# 是否抽中
hasLots = False
# 1. 循环三次
i = 0
while i < 3:
# 2. 每一次循环抽签(获取1-9随机数)
num = random.randint(1, 9)
print(f'抽签结果:{num}')
# 抽中, 原谅 停止抽签
if num==6:
print('很幸运,媳妇原谅')
# 修改变量
hasLots = True
break
i += 1
# 循环结束之后判断是否有抽中过
if not hasLots:
print('跪搓衣板')
in和not in
判断元素是否在容器中
s = 'hello world'
result = 'z' in s
result = 'd' not in s
print(result)
输入一个字符串判断是否里面包含i这个字母(不能使用in或not in)
包含就输出包含i,不包含输出不包含
# 1. 输入字符串
s = input('请输入字符串')
# 2. 遍历字符串
for ele in s:
# 3. 查看元素是否是i
# 是 直接输出包含 break
if ele=='i':
print('包含')
break
else:
print('不包含')
高级变量类型
- 字符串
- 列表
- 元组
- 集合
- 字典
字符串
特点
-
有序: ‘hello world’
-
不可改变 字符串不可变数据类型
字符串修改,并不是修改原来的字符串 修改完之后返回一个新的字符串
字符串定义
s = 'hello world‘ #单引号
s = "hello world" #双引号
s = ''' #三引号原样输出字符串
'''
s = """
"""
#单引号,双引号,三引号的区别
#单引号必须加\才能输出换行,但三引号是原样输出,''' '''中是什么样就原样输出,包括回车换行
s = 'hello'\
'world'
在字符串中,如果要输出特殊符号,在特殊字符前加转义符’\‘
查询单个元素-索引
str[下标]
使用索引或下标查询
索引从0开始
也可以从后往前数,最后一个数的下标是 -1
str1 = 'abcdefg'
print(str1)
# 数据在程序运行过程中存储在内存
# ? 得到数据a字符, 得到数据b字符 -- 使用字符串中某个特定的数据
# 这些字符数据从0开始顺序分配一个编号 -- 使用这个编号精确找到某个字符数据 -- 下标或索引或索引值
# str1[下标]
print(str1[-7])
print(str1[0])
查询多个元素-切片
序列变量[开始索引:结束索引:步长]
[开始索引,结束索引) --左闭右开
# s = 'abcdefghijk'
# -------------- 基础切片 -------------- #
# defg
# ele = s[3:7:1]
# 步长默认是1 可以省略
# ele = s[3:7:]
# ele = s[3:7]
# 步长不为1
# ele = s[3:7:3]
# abcd
# ele = s[0:4]
# 正序输出 开始索引是0 或 倒序输出开始索引是最后一个元素 可以省略
# ele = s[:4]
# hijk
# ele = s[7:15]
# 正序输出 结束索引 最后一个元素索引 或 倒序输出 结束索引是第一个元素 可以省略
# ele = s[7:]
# 开始到结尾
# ele = s[:]
# -------------- 索引或步长为负数 -------------- #
s = 'abcdefghijk'
# 步长为负 倒序输出
# ele = s[-4:3:-1]
# ele = s[:-5:-1]
# ele = s[3::-1]
# print(ele)
ele = s[::-1]
print(ele)
注意:
省略步长
省略开始索引
省略结束索引
步长为负
若输出方向与步长相反是无法识别出来的
查询元素的索引和个数
index或find查询元素索引
str.find(子串,开始位置,结束位置) --如果找到,返回第一个索引,获取失败则返回-1
mystr = "hello world and itcast and itheima and Python"
index = mystr.find('and',15,100)
index = mystr.index('and')
# 从右边获取
mystr.rindex()
mystr.rfind()
注意:
find和rfind 查找不到 返回-1
index和rindex查找不到 程序报错停止 在 一些比较重要的代码会使用这种方式
count查询元素的个数
c = mystr.count('and')
print(c)
字符串修改
所谓修改字符串,指的就是通过函数的形式修改字符串中的数据。
字符串不可变数据类型
字符串修改,并不是修改原来的字符串 修改完之后返回一个新的字符串
替换replace
# 参数1: 需要被替换的字符串
# 参数2: 替换之后的字符串
# 参数3: 替换次数,默认-1 替换所有
new_str = mystr.replace('and', 'he',2)
分割字符串split
# 参数1: 分割符
# 参数2: 分割最大次数 默认-1 分割所有,分割后为(分割次数+1)个部分
# 参数3:从哪个方向取,0为正向,-1从后向前
# 返回值为[]
list1 = mystr.split('and',1)[0]
list1 = mystr.split('and',1)[-1]
组合join
mylist = ['aa', 'bb', 'cc']
# aa*bb*cc
# # aa...bb...cc
s = '...'
# join参数 是可迭代的序列,每一个元素都是字符串类型
new_str = s.join(mylist)
将字符串第一个支字符转换成大写capitalized()
mystr = "hello world and itcast and itheima and Python"
# 结果:Hello world and itcast and itheima and python
print(mystr.capitalize())
注意:capitalized()函数转换后,只字符串第一个字符大写,其他的字符全都是小写
将字符串每个单词首字母转换成大写title()
mystr = "hello world and itcast and itheima and Python"
# 结果:Hello World And Itcast And Itheima And Python
print(mystr.title())
大写转小写lower()
mystr = "hello world and itcast and itheima and Python"
# 结果:hello world and itcast and itheima and python
print(mystr.lower())
小写转大写upper()
mystr = "hello world and itcast and itheima and Python"
# 结果:HELLO WORLD AND ITCAST AND ITHEIMA AND PYTHON
print(mystr.upper())
删除字符串左侧空白字符Istrip()
mystr = " hello world and itcast and itheima and Python "
new_str = mystr.lstrip()
删除字符串右侧空⽩字符rstrip()
new_str = mystr.rstrip()
删除字符串两侧空⽩字符strip()
new_str = mystr.strip()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bJa8zaKG-1628652111877)(E:\总结笔记\img\1.png)]
字符串判断
所谓判断即是判断真假,返回的结果是布尔型数据类型:True 或 False
判断是否以指定子串开头startswith()
# 字符串序列.startswith(⼦串, 开始位置下标, 结束位置下标)
mystr = "hello world and itcast and itheima and Python "
# 结果:True
print(mystr.startswith('hello'))
# 结果False
print(mystr.startswith('hello', 5, 20))
判断是否以指定⼦串结尾endswith()
# 字符串序列.endswith(⼦串, 开始位置下标, 结束位置下标)
mystr = "hello world and itcast and itheima and Python"
# 结果:True
print(mystr.endswith('Python'))
# 结果:False
print(mystr.endswith('python'))
# 结果:False
print(mystr.endswith('Python', 2, 20))
判断是否所有字符都是字母isalpha()
mystr1 = 'hello'
mystr2 = 'hello12345'
# 结果:True
print(mystr1.isalpha())
# 结果:False
print(mystr2.isalpha())
判断是否只包含数字isdigit()
mystr1 = 'aaa12345'
mystr2 = '12345'
# 结果: False
print(mystr1.isdigit())
# 结果:False
print(mystr2.isdigit())
判断是否都是字母或数字isalnum()
mystr1 = 'aaa12345'
mystr2 = '12345-'
# 结果:True
print(mystr1.isalnum())
# 结果:False
print(mystr2.isalnum())
判断是否只包含空白isspace()
mystr1 = '1 2 3 4 5'
mystr2 = ' '
# 结果:False
print(mystr1.isspace())
# 结果:True
print(mystr2.isspace())
字符串拼接
-
加号
print 'Python' + 'Tab' # PythonTab
-
逗号
print 'Python','Tab' # Python Tab
-
直接连接
print 'Python''Tab' #PythonTab print 'Python' 'Tab' #PythonTab
-
格式化
print '%s %s'%('Python', 'Tab') #Python Tab
-
join
str_list = ['Python', 'Tab'] a = '' print a.join(str_list) #PythonTab
-
多行字符串拼接
s = ('select *' 'from atable' 'where id=888') print s, type(s) #输出 #select *from atablewhere id=888 <type 'str'>
列表
简介
可扩展顺序表:
类型:list 可变类型数据
python里面没有数组
list可以存储任意数据类型
特点
有序:索引 查询元素索引
可变:增加 删除 修改
获取元素
获取单个元素
索引获取 list[下标]
获取多个元素
切片获取多个元素 list[开始索引:结束索引:步长] --左闭右开
查找元素索引
list.index(数据, 开始位置下标, 结束位置下标)
name_list.index('TOM',0,1) #返回查询到的第一次出现的索引,若找不到不会报错
不存在报错
查找元素个数
list.count(元素)
name_list.count(10)
len
求容器元素个数 len(list)
str list tuple set dict求长度
添加元素
末尾追加元素 append
name_list = ['TOM', 'Lily', 'ROSE']
name_list.append([11, 22])
extend 拆分容器中的数据追加
extend传入的数据必须使可迭代的,否则会报错
name_list = ['TOM', 'Lily', 'ROSE']
name_list.extend('xiaoming') #输出 ['TOM', 'Lily', 'ROSE','x','i','a','o','m','i','n','g']
某一个位置插入元素 insert
name_list = ['TOM', 'Lily', 'ROSE']
# name_list.insert(下标, 数据)
name_list.insert(-1, 'aaa')
删除
删除指定索引元素
del 列表[索引]
删除整个列表
a = 10
del a
print(a) #a变量无法使用,同理del list也是一样
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QGchdeAi-1628652111878)(E:\总结笔记\img\2.png)]
当我们定义了一个变量后,在内存中就申请了一个内存空间,内存空间中存的是变量的地址,如上面第一个图,当执行del时,就将内存空间中存储的地址删除了,内存就会被释放掉(python中是自动的内存回收,一旦没有指向,就会被删除),如第二图,就无法找到数据。
删除并返回元素
列表.pop(索引)
删除指定元素
列表.remove(元素名) #只删除第一出现的该元素
清空列表
将列表中的数据清除,变成一个空的列表,下次还是可以正常使用
列表.clear()
列表修改
修改某一个元素
name_list = ['TOM', 'Lily', 'ROSE']
# 1. 修改指定下标的数据
name_list[0] = 'aaa'
列表逆置
list1 = [1, 3, 2, 5, 4, 6]
list1.reverse()
列表排序
# 参数1 key: 传递比较规则
# 参数2 reverse:逆序排序 降序
list1.sort(reverse=False)
列表的拷贝
# 定义变量保存列表数据
l = [1,2,3]
# print(l)
# l赋值给ll变量
# ll = l
ll = l.copy() #浅拷贝
# 修改ll
ll.append(10)
print(ll)
# l也发生了变化
print(l)
注意:
如果直接赋值 使用同一个列表的空间,一个修改,另外一个也修改,如下第一个图
如果使用copy赋值,修改一个,并不会影响另一个,如下第二个图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-18AciLNe-1628652111880)(E:\总结笔记\img\4.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NUecUoBt-1628652111881)(E:\总结笔记\img.png)]
列表遍历
while遍历列表的索引
对于无序的数据是无法通过while进行循环的
i = 0
while i < len(name_list):
print(name_list[i])
i += 1
for循环遍历
name_list = ['TOM', 'Lily', 'ROSE']
for i in name_list:
# 遍历序列中的数据
print(i)
遍历的时候删除元素
alist = [10,15,13,14,16]
# 遍历列表的时候把所有的元素删除掉
for ele in alist:
print(ele)
# 删除元素
alist.remove(ele)
print(alist)
执行之后的列表中有:15,14
由于删除元素的时候,后面的元素向前占位
解决方案:可以从尾部遍历 删除
# 开始索引
i = len(alist) - 1
while i > -1:
print(alist[i])
del alist[i]
i -= 1
print(alist)
列表嵌套
name_list = [['TOM', 'Lily', 'Rose'], ['张三', '李四', '王五'],10, ['xiaohong', 'xiaoming', 'xiaolv']]
name_list[1].append('赵六')
例题
# 需求:8位老师,3个办公室, 将8位老师随机分配到3个办公室
# 每一个办公室至少有一名老师
import random
# -------------- 需求1 -------------- #
# 需求:8位老师,3个办公室, 将8位老师随机分配到3个办公室
# 1. 准备数据
# teachers = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
# offices = [[], [], []]
#
# for name in teachers:
# num = random.randint(0, 2)
# offices[num].append(name)
# teachers.clear()
# print(offices)
# -------------- 需求2 -------------- #
# 需求:8位老师,3个办公室, 将8位老师随机分配到3个办公室
# 每一个办公室至少有一名老师
# -------------- 方案一 -------------- #
# 分配完成之后 是否满足 不满足继续当前操作
# # 1. 准备数据
# teachers = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
# offices = [[], [], []]
#
# # while len(offices[0])==0 or len(offices[1])==0 or len(offices[2])==0:
# while [] in offices:
# # offices中所有的列表全部清空
# for office in offices:
# office.clear()
#
# for name in teachers:
# num = random.randint(0, 2)
# offices[num].append(name)
# teachers.clear()
# print(offices)
# -------------- 方案二 -------------- #
# 1. 随机找三个老师 分配到三个办公室中
# 2. 剩下的老师 随机分配
teachers = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
offices = [[], [], []]
# # 1. 随机找三个老师 分配到三个办公室中
# for office in offices:
# # 随机分配老师
# # 随机找一个老师索引
# i = random.randint(0, len(teachers) - 1)
# # 找到这个老师
# teacher = teachers[i]
# # 添加到办公室中
# office.append(teacher)
# # 删除这名老师
# del teachers[i]
# 1. 随机找三个老师 分配到三个办公室中
for office in offices:
# # 随机分配老师
# # 随机找一个老师索引
# i = random.randint(0, len(teachers) - 1)
# # 找到这个老师
# teacher = teachers[i]
# # 添加到办公室中
# office.append(teacher)
# # 删除这名老师
# del teachers[i]
#先找到,再删除,并获取删除后的值,可以直接使用pop()
# ele =
office.append(teachers.pop(random.randint(0, len(teachers) - 1)))
# print(teachers)
# print(offices)
# 2. 剩下的老师 随机分配
for name in teachers:
# 随机找办公室
num = random.randint(0, 2)
# 添加到办公室中
offices[num].append(name)
teachers.clear()
print(offices)
回顾
字符串
- 有序 ‘hello world’
- 不可变(不能修改原来的字符串)
增删改查
查询:索引 切片 index/find
修改:修改字符串返回新的字符串 replace split join
开头/结尾:startswith endswith
字母/数字/数字字母: isalpha isdigit isalnum
列表
- 有序
- 可变
增加:append insert extend
删除: 索引:del 列表[索引] 元素:列表.remove(元素) 删除并返回:列表.pop(索引)
修改:列表[索引] = 值
查询:单个元素:列表[索引] 多个元素:切片 元素索引:index
嵌套:多层索引查询
元组
特点
类似列表,和列表最大区别是不可变
类型:tuple
- 有序
- 不可变
增 删 改 查
查询: 单个:索引 多个:切片 元素索引:
定义
# 1. 多个数据元组
t1 = (10, 20, 30)
# 2. 单个数据的元组
t2 = (10,)
注意:单个元素元组需要加上逗号
查找
t1 = ('aa', 'bb', 'cc', 'bb')
# 1. 下标
print(t1[0])
# 查询多个元素
print(t1[0:2])
# 2. index()
# print(t1.index('bb')) 查不到则报错
if 'bbb' in t1:
print(t1.index('bbb'))
# 3.count()
# 统计某个数据在当前元组出现的次数
t1.count('bb')
元素修改
如果元组里面有列表,修改列表里面的数据是支持的
t2 = ('aa', 'bb', ['cc', 'dd'])
# 不能修改元组元素
t2[2] = [1,2,3]
# 可以修改可变元素中的数据
t2[2][0] = 'TOM'
元组的应用场景
自动组包
将离散的数据组合起来
t = (1,2,3)
a,b = 10,20
a = 10,20
print(type(a)) #a是元组类型
自动解包
t = (1,2,3)
a,b,c = t[0],t[1],t[2] #解包
# 一定要注意:等待赋值的元素个数要与元组中元素的个数对应
a,b,c = t #简便写法
print(a,b,c)
组包和解包使用场景
# 数据交换
a = 10
b = 20
# 申请一块空间
tmp = a
a = b
b = tmp
print(a,b)
# 不用申请额外的空间
a = a+b
b = a-b
a = a-b
print(a,b)
# 元组组包和解包方式实现
# 先组包 再解包
a,b = b,a # (20,10)
print(a,b)
# 函数多返回值
# 函数参数传递数据
格式化输出
t = ('张三',30,78.5)
print('姓名:%s,年纪:%d'%(t[0],t[1])) #有两个以上的元组元素就要加括号
print('姓名:%s,年纪:%d'%t) #如果需要元组中的所有元素,则不用将原则解包再组包,直接用元组t
print('姓名:%s'%t[0])
让列表不可被修改,保护数据安全
l = [1,2,3]
# 列表转换成元组类型
t = tuple(l)
print(t)
字典
人: 姓名 性别 年纪 [‘张三’,‘男’,30]
字典 跟顺序无关
特点
- 键值对
- 无序 没有索引,可以把key看成索引 key不能重复
- 可变
- key 必须是不可变类型数据 int float bool str tuple
字符串 列表 元组
[‘张三’,‘李四’]
每一个信息包含多个属性,可以使用字典存储
定义
字典类型会根据key做hash运算(类似于提取一个指纹),根据这个指纹找到再什么地方存储。因此,并不是什么数据类型都可以的,必须是不可变类类型的数据
# 有数据字典
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
# 空字典
dict2 = {}
dict3 = dict()
增加
如果key存在则修改这个key对应的值;如果key不存在则新增此键值对。
字典[key]=value
删除
del() / del:删除字典或删除字典中指定键值对
key = 'names'
if key in dict1:
del dict1[key] # 报错
print(dict1)
注意:字典中in 和not in判断的是key是否存在
clear():清空字典
dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
dict1.clear()
print(dict1) # {}
修改
字典[key]=value
key不存在增加,存在就是修改
查询
查询元素
if key in 字典:
字典[key]
key不存在报错
dict1.get(key, 默认值)
如果key不存在就返回默认值
获取所有的key value以及item
# keys() 查找字典中所有的key,返回可迭代对象
dict1.keys()
print(dict1.keys()) # dict_keys(['name', 'age', 'gender'])
# keys() values,返回可迭代对象
dict1.values()
print(dict1.values()) # dict_values(['Tom', 20, '男'])
#items() 查找字典中所有的键值对,返回可迭代对象,里面的数据是元组,元组数据1是字典的key,元组数据2是字典key对应的值
dict1.items()
print(dict1.items()) # dict_items([('name', 'Tom'), ('age', 20), ('gender',
'男')])
遍历
-
key
for ele in dict1: print(ele) for key in dict1.keys(): print(key)
-
所有的values
for value in dict1.values(): print(value)
-
所有的key和value
for ele in dict1: print(ele,dict1[ele]) for key, value in dict1.items(): #元组的解包和拆包 # print(key) # print(value) # 目标: key=value print(f'{key}={value}')
字典小练习
'''
已知班级为三班,目前学生有:张三,李四,王五。他们的年龄分别为11,12,13。
请思考可行的方案将他们三个人的信息进行存储。
类和对象
静态属性
动态行为
分析:
1. 一个学生存储 字典 name age
2. 所有学生存储 列表
'''
# 1. 一个学生存储 字典 name age
stu1 = {'name':'张三','age':11}
stu2 = {'name':'李四','age':12}
stu3 = {'name':'王五','age':13}
# 2. 所有学生存储 列表
stus = [stu1,stu2,stu3]
# print(stus)
for stu in stus:
print(f'姓名:{stu["name"]},年纪:{stu["age"]}')
#这里作为key的name如果用双引号记得要加转义字符
集合
特点
- 无序 没有索引
- 可变类型
- 去重
- 集合元素必须是不可变类型
创建
创建集合使⽤ {} 或 set() , 但是如果要创建空集合只能使⽤ set() ,因为 {} ⽤来创建空字典。
s2 = {10, 30, 20, 10, 30, 40, 30, 50}
print(s2)
s3 = set('abcdefg')
print(s3)
增加
add添加一个元素,并且必须是不可变类型(因为无索引,因此必须可哈希),因此不可以添加列表,但可以添加元组
update上传的是一个可迭代的数据
# 添加一个元素
s1.add(100)
# 将 序列中元素拆分添加,
s1.update([10, 20, 30, 40, 50])
删除
- remove(),删除集合中的指定数据,如果数据不存在则报错。
- discard(),删除集合中的指定数据,如果数据不存在也不会报错。
- pop(),随机删除集合中的某个数据,并返回这个数据。
# 根据元素删除
集合.remove(元素)
集合.discard(元素)
# 删除并返回
集合.pop()
pop没有参数 就是随机删除
discard不存在不做任何操作
查询和修改
没有索引,不能根据索引查询 不能根据索引修改对应的数据
遍历
d = {1,2,3}
for ele in d:
print(ele)
set集合去重
l = [1,2,3,1,2,3]
# 转换成set集合
# s = set('hellohello')
s = set(l)
高级变量类型回顾
str
- 有序
- 不可变类型
- 可以重复
增加:不能
删除:不能
修改:不能
查询: 单个:索引 多个:切片 元素索引:index/find
组合新字符串并返回:
- replace
- split
- join
- isalpha
- isdigit
- isalnum
list
- 有序 索引
- 可变
- 可以重复
增加: 尾部增加:append 特定位置增加:insert 序列:extend
删除: 索引:del 列表[索引] 元素:列表.remove(元素) 删除并返回:pop(索引)
修改:索引 列表[索引] = 值
查询: 单个:索引 多个:切片 元素索引:index
tuple
- 有序
- 不可变
- 可以重复
增加:不能
删除:不能
修改:不能
查询: 单个:索引 多个:切片 元素索引:index
字典
- 无序
- 可变
- key不能重复
增加: 字典[key]=value
删除: key: del 字典[key]
修改🔑 字典[key]=value
查询: key: 字典[key]
获取:所有的key 所有value 所有条目items
集合
- 无序
- 可变
- 不能重复
增加:可以 add 序列:update()
删除: 元素 集合.remove(元素) discard:不存在不报错 pop 删除并返回
修改: 不能修改元素
查询: 不能查询
range 区间
定义:用于数字连续遍历 range(开始,结束,步长) --左闭右开
# r = range(0,10,1) #0,1,2,3,4,5,6,7,8,9
# r = range(0,10,2)
r = range(10,2,-1) #倒序
r = range(10) #省略开始,并省略步长
从0开始可以省略0
步长默认为1 可以省略
练习
l = ['张三', '李四', '李四', '李四', '王五'] # 遍历列表l 打印每一个元素 里面所有的李四删除 for循环实现 # 倒序删除
答案:
# -------------- while倒序 -------------- #
i = len(l) - 1
while i > -1:
if l[i]=='李四':
del l[i]
i -= 1
print(l)
# -------------- for倒序 -------------- #
for index in range(len(l) - 1,-1,-1):
print(index)
if l[index]=='李四':
del l[index]
print(l)
高级变量类型公共语法
公共运算符
+(合并)
合并两个数据,支持 str list tuple 这种可重复的数据类型可以重复
'hello'+'hello'
[1,2,3]+[4,5,6]
*(复制)
变量*数字 支持 str list tuple,随机删除集合中的某个数据,并返回这个数据。
'hello'*3
in和not in
元素是否在容器中 支持所有的高级变量类型
公共方法
方法名 | 含义 |
---|---|
len | 元素个数(所有高级变量类型) |
del | 删除变量内存指向 |
max/min | 最大值或最小值(字典比较key),可以提取比较键进行自定义比较 对于列表中元素是字典类型的将无法比较,这种情况可以对提取比较键来处理 |
enumerate
遍历的时候增加索引,遍历后为元组
# for i in enumerate(list1, start=1): #遍历后为元组
# for index,value in enumerate(list1, start=1):
for index,value in enumerate({'name':'张三','age':30}, start=1): #遍历后元组解包再组包
print(index,value) #遍历字典的话只遍历key
数据类型转换
list1 = [10, 20, 30, 20, 40, 50]# 可变 重复
s1 = {100, 300, 200, 500} # 可变 不能重复
t1 = ('a', 'b', 'c', 'd', 'e') # 不可变
# tuple(): 转换成元组
# print(tuple(list1))
# print(tuple(s1))
# list():转换成列表
# print(list(s1))
# print(list(t1))
# set():转换成集合
# print(set(list1))
# print(set(t1))
推导式
可变类型才有推导式 list set dict
快速创建容器数据
列表推导式
推导式基础语法
# for 实现--------------
list1 = []
for i in range(11):
list1.append(i)
print(list1)
# 列表推导式实现------------------------
list1 = [i for i in range(10)]
print(list1)
# 添加a1 a2...a20
list2 = ['a'+str(i) for i in range(1,21)]
for循环只是次数显示 跟添加数据没有关系
推导式if语句
# 2. for循环加if 创建有规律的列表
list2 = []
for i in range(10):
if i % 2 == 0:
list2.append(i)
print(list2)
# 3. 把for循环配合if的代码 改写 带if的列表推导式
list3 = [i for i in range(10) if i % 2 == 0]
print(list3)
多for推导式
list1 = []
for i in range(1, 3):
for j in range(3):
# 列表里面追加元组: 循环前准备一个空列表,然后这里追加元组数据到列表
list1.append((i, j))
print(list1)
# 多个for实现列表推导式
list2 = [(i, j) for i in range(1, 3) for j in range(3)]
print(list2)
练习
#将0到100的列表每三个分成一份
#[1,2,3],[4,5,6],[7,8,9],[97,98,99],[100]
list = [i for i in range(101)]
[l[index:index+3]for index in range(len(list)) if index % 3 == 0]
字典推导式
基础语法
dict1 = {i: i**2 for i in range(1, 5)}
print(dict1)
多个列表生成字典
list1 = ['name', 'age', 'gender','id']
list2 = ['Tom', 20, 'man']
dict1 = {list1[i]: list2[i] for i in range(len(list2))}
print(dict1)
# for ele in zip(list1,list2):
# print(ele)
d = {key:value for key,value in zip(list1,list2)} #将两个list打包进行遍历
print(d)
注意zip用法
列表推导式过滤
l = [{'name':'张三','age':30},{'name':'李四','age':40},{'name':'王五','age':50}]
# 过来年纪大于35的人 组成新的列表
new_l = [ele for ele in l if ele['age']>35]
集合推导式
list1 = [1, 1, 2]
set1 = {i ** 2 for i in list1}
print(set1)
函数基础
- 完成功能
- 优化 代码简化(代码复用) 程序执行效率
作用
代码复用
语法
# 定义
def 函数名():
函数执行代码
# 函数名()
函数特点
- 只定义函数,如果没有调用,函数不会执行
- 执行函数,进入函数内部代码执行,执行完之后回到调用的地方继续向下执行(debug)
- 先定义再使用
参数
增加函数通用性
- 形参和实参个数匹配
- 形参函数定义的时候并没有赋值,调用的时候会把实参传递给形参
返回值
return返回数据
def add(a,b):
result= a+b
# print(result)
return result
l = []
# 获取计算之后的结果 保存列表中
result1 = add(10, 20)
result2 = add(30, 40)
python如果函数没有返回值 返回的是None
return注意点
- return 执行之后后续代码不再执行
- return可以没有返回值单独执行,代表停止函数执行
函数练习
def my_max(a,b):
c = a if a>b else b
return c
def my_max(a,b):
if a>b:
return a
else:
return b
result = my_max(10, 20)
print(result)
函数的说明文档
解释型 动态数据类型 面向对象
def sum_num1(a, b):# 不能限制传递数据类型
'''
求两个数的和
:param a: 第一个int类型数据
:param b: 第二个int类型数据
:return: 返回int类型数据
'''
return a + b
Ctrl+Q查看说明文档
函数嵌套调用
def testB():
print('B函数开始-----')
print('这是B函数')
print('B函数结束-----')
# 函数内部功能越小越好
# A函数
def testA():
print('A函数开始-----')
# 嵌套调用B
testB()
print('A函数结束-----')
注意:
- 执行顺序
- 抽取函数的原则,尽量独立的小的功能封装成多个函数
def print_line():
print('-' * 20,end='')
print('*' * 20)
# print_line()
# 2. 函数嵌套调用 实现多条横线
def print_lines(num):
i = 0
while i < num:
print_line()
i += 1
函数嵌套调用案例
# -------------- 练习1 -------------- #
'''
任意给出两个数字,返回最小的数字值
'''
def two_min(a,b):
if a<b:
return a
else:
return b
# result = two_min(10, 20)
# print(result)
# -------------- 练习2 -------------- #
'''
任意给出三个数字,利用函数嵌套返回最小的数字值.
'''
# 10 20 30
def three_min(a,b,c):
# 比较前两个 获取较小值
min = two_min(a,b)
# 较小值和最后一个比较 返回最小值
min_result = two_min(min,c)
return min_result
result = three_min(10, 20, 30)
print(result)
time
睡眠
time.sleep(秒)
局部变量和全局变量
局部变量
函数内部定义的变量
作用域: 只能在函数内部使用
生命周期:调用函数指定到定义变量的时候创建 函数执行完之后自动销毁
不同的函数中可以定义同名的局部变量
# 定义一个函数,声明一个变量:函数体内部访问、函数体外面访问
def testA():
a = 100
print(a) # 函数体内部访问,能访问到a变量
全局变量
直接定义再py文件中的变量
作用域:整个py 可以通过导入使用
生命周期:执行定义的代码创建 程序停止才会销毁(del a)
函数内部修改全局变量
# B函数想要a的取值是200
a = 100
def testB():
global a # 声明a为全局变量
a = 200
print(a)
注意:在函数内部修改可变类型
-
如果是对给全局变量赋值的数据进行添加元素等,不用加global(只是在原列表中添加了元素,全局变量指向的列表地址并不变)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rFJJkomj-1628652111882)(E:\总结笔记\img\6.png)]
-
如果是整体修改全局变量需要加global
l= [1,2,3]
def func():
# global
# 函数内部修改可变类型的全局变量
# l.append(10) # 不需要使用global
l = [4,5,6] # 需要使用global
函数的多返回值
多个结果通过高级变量类型包装返回
- return后用逗号并列返回多个数据,返回的是元组
- return后面可以直接书写 元组 列表 字典,返回多个值
def return_num():
return 1, 2 # 返回的是元组
# return后面可以直接书写 元组 列表 字典,返回多个值
# return (10, 20)
# return [100, 200]
# return {'name': 'Python', 'age': 30}
a,b = return_num() #组包后拆包
print(a,b)
特殊的参数
位置参数
实参传递的时候要和形参个数保持一致 顺序保持一致
关键字参数
使用关键字参数可以不按照形参的顺序传递
def user_info(*,name, age, gender):
print(f'您的姓名是{name}, 年龄是{age}, 性别是{gender}')
* 代表必须使用关键字参数
解决问题
参数比较多,传递的时候会发生顺序错误
默认参数
可以给形参设置默认值,就是默认参数
调用函数的时候默认参数可以传递,也可以不传递
传递数据使用的传递的数据,不传使用的是默认值
默认参数需要放到最后
def user_info(name, age, gender='男'):
print(f'您的姓名是{name}, 年龄是{age}, 性别是{gender}')
user_info('TOM', 18) # 没有为缺省参数传值,表示使用默认值
user_info('TOM', 18, gender='女') # 为缺省参数传值,使用这个值,即修改了默认值
方法/函数重载
函数名称相同,参数不同
python没有方法重载,不能有同名的方法
默认参数作用
可以解决其它语言中方法重载问题
# 1. 网址 2. 请求方式 GET/POST
# 程序: 30个网址 25 GET 5 POST
def sendRequest(url,method='GET',params=''):
'''
请求服务器
:param url: 请求网址
:param method: 请求方式GET/POST
:return:
'''
print(f'请求地址:{url},请求方式:{method}')
sendRequest('http://www.baidu.com')
sendRequest('http://www.baidu.com/login','POST')
sendRequest('http://www.baidu.com/login','POST')
sendRequest('http://www.baidu.com/login','POST')
sendRequest('http://www.baidu.com/login','POST')
可变参数*args
# 接收所有位置参数,返回一个元组
def user_info(a,*args):# *告诉解释器这是一个可变参数
print(args)
# user_info('TOM')
# user_info('TOM', 20)
user_info('TOM', 20, 'man')
注意:
- 可变参数需要放到参数最后面
- 如果前面有其它参数 前面的参数先匹配之后的才传递给args
可变参数kwargs
获取不存在的关键字参数
# 收集所有关键字参数,返回一个字典
def user_info(name,**kwargs):
print(kwargs)
# user_info()
# user_info(name='TOM')
user_info(name='TOM', age=20)
传递元组或字典给可变参数
传递元组给可变参数args
def func(*args):
print(args)
# 保存结果
sum = 0
# 遍历 相加
for ele in args:
sum += ele
# 返回结果
return sum
t = (10, 20, 30)
result = func(*t) #若想将一个元组传入函数将里面的元素遍历出来,传参的时候加*拆包
通过*解包
def func(name,age):
print(name,age)
t = ('张三',30)
# func(t[0],t[1])
func(*t)
传递字典给可变参数kwargs
def func(**kwargs):
print(kwargs)
d = {'name': '张三', 'age': 30}
# func(name='张三',age=30)
func(**d)
需要通过**对字典解包
字典拆包
dict1 = {'name':'TOM','age':20}
#字典中有两个键值对,拆包的时候用两个变量接收数据
a,b = dict1
引用
数据类型
int float bool str tuple list set dict
引用
引用就是变量指向数据存储空间的现象
使用id(数据/变量)操作获取数据存储的内存空间引用地址 引用地址只是一种现象
不可变数据类型引用 –int float bool str tuple
数据相同,引用地址相同
可变数据类型引用
list
只要是不同的变量,引用地址都不同
赋值 l2 = l1,引用地址相同
copy,引用不同
[:],引用地址不同
dict
只要是不同的变量,引用地址都不同
set
只要是不同的变量,引用地址都不同
可变类型和不可变类型
判断依据:数据存储空间能不能被修改
若存储空间中的数据可以被修改,则为可变类型
若存储空间中的数据不能被修改,只能重新开辟新的空间,则为不可变类型
不可变类型
int float bool str tuple
可变类型
存储空间可以被修改
list set dict
传递可变类型和不可变类型给函数
传递不可变类型给函数
def func(a):
a = 10
m = 20
func(m) #m传入函数后相当于将m地址传给了a
print(m) #m = 20
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2P6ypAOV-1628652111883)(E:\总结笔记\img\7.png)]
传递可变类型给函数
传递可变类型数据给函数,函数 内部可以修改可变类型数据的存储空间
def func(l):
# l = [4,5,6]
l.append(10)
#del l
ll = [1,2,3]
func(ll)
print(ll) #ll = [1,2,3,10],
#如果执行了l = [4,5,6],输出ll = [1,2,3],因为l存储的就不在是【1,2,3】的空间地址 了,而是【4,5,6】的地址,l增加的10也将增加在【4,5,6】中,与【1,2,3】无关
递归
递归
把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
递归使用场景
文件遍历
二分查找 快速排序
递归特点
- 函数内部调用自己
- 必须有出口 结束递归的条件(重点)
递归代码实现
# 1. 明确目标
# 2. 出口 num=1
def my_sum(num):
'''
求num以内的数组累加和
:param num:
:return:
'''
if num == 1:
return 1
return num + my_sum(num - 1)
result = my_sum(3)
递归执行流程
函数嵌套调用
递归和循环
递归:
优点:编写简单 缺点:不能层级过深 ,容易内存溢出
循环:
优点:不用额外申请内存 缺点:有些需求不太容易使用while表现出来
python最大层级:990多
jvm:6万
go:9万
40亿
lambda
lambda
匿名函数
lambda表达式必须只有一行表达式
lambda 参数:表达式
def 函数名(参数):
表达式
lambda表达式语法
func = lambda: 100 #可以将lambda表达式提取出变量
print(func())
特点:
参数在:之前
自动返回:表达式结果
需要加上()调用
lambda参数写法
# 1. 函数
def add(a, b):
return a + b
result = add(1, 2)
print(result)
# 2. lambda
fn1 = lambda a, b: a + b
print(fn1(2, 3))
练习1
def my_max(a,b):
if a>b:
return a
else:
return b
func = lambda a, b: a if a > b else b
result = func(10, 20)
print(result)
lambda表达式默认参数
fn3 = lambda a, b, c=100: a + b + c
print(fn3(10, 20))
print(fn3(10, 20, 200))
lambda表达式可变参数args
fn4 = lambda a,*args: args
print(fn4(10, 20))
注意:可变参数需要放到最后
lambda表达式kwargs
fn5 = lambda **kwargs: kwargs
print(fn5(name='Python'))
高阶函数
高阶函数作用
增加函数的通用性
- 数据的通用性
- 操作的通用性
高阶函数
函数有函数参数就是高阶函数
def cacl(a,b,func):# a 10 b 20 func<=>add
'''
根据操作返回结果
:param a: 数据1 int
:param b: 数据2 int
:param func: 操作 函数 func<=>add 如果输出func就是函数的地址
:return: 根据func操作返回结果
'''
# add(10,20)
# add(a,b)
result = func(a,b)
return result
高阶函数传递系统函数
系统函数是内置的一些函数
def sum_num(a, b, f):
return f(a) + f(b)
result1 = sum_num(-1, 5, abs)
print(result1)
result2 = sum_num(1.1, 1.3, round)
print(result2)
常用的高阶函数
list类型的sort排序
students = [
{'name': 'TOM', 'age': 20},
{'name': 'ROSE', 'age': 19},
{'name': 'Jack', 'age': 22}
]
'''
如果要排序的话需要比较大小,上面的字典直接是无法判断大小的
key:传入函数参数,用来提取比较键
'''
#模拟list的sort方法
def sort(l,func):
new_l = [] #将比较键提取出来放入新的list中
for ele in l:
#需要提取比较键
new_ele = funct(ele)
new_l.append(new_ele)
return
# age排序
# students.sort(key=lambda ele:ele['age']) #key 是比较键,也就是比较的法则,需要传入定义比较的函数;lambda函数表示的是将studens列表的每个元素作为参数传入,返回字典元素age关键字对应的value值
# print(students)
# 姓名最后一个字母排序
students.sort(key=lambda ele:ele['name'][-1])
print(students)
内置高阶函数 --max()
max(序列,key = func) --key的用法和list中sort一样
内置高阶函数 --map()
map(func, lst),将传⼊的函数变量func作⽤到lst变量的每个元素中,并将结果组成迭代器(Python3)返回。
list1 = [1, 2, 3, 4, 5]
# 把列表里面每一个元素 传递到函数中
# 返回一个新的数据 把新的数据组成迭代器返回
def func(ele):
return ele**2
result = map(func, list1)
print(list(result))
模拟map源代码
def my_map(l,func):
# 接收结果
new_l = []
for ele in l:
# 处理
new_ele = func(ele)
# 处理的结果添加到结果中
new_l.append(new_ele)
return new_l
内置高阶函数 --reduce()
reduce(func,lst),其中func必须有两个参数。每次func计算的结果继续和序列的下⼀个元素做累积计算。
注意:reduce()传⼊的参数func必须接收2个参数。
list1 = [1, 2, 3, 4, 5]
# 1. 导入模块
import functools
# 2. 定义功能函数
def func(a, b):
return a * b
# 3. 调用reduce,作用:功能函数计算的结果和序列的下一个数据做累计计算
result = functools.reduce(func, list1)
print(result)
内置高阶函数 --filter()
filter(func, lst)函数⽤于过滤序列, 过滤掉不符合条件的元素, 返回⼀个 fifilter 对象。如果要转换为列表, 可以使⽤ list() 来转换。
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def func(ele):
return ele%3==0
#
# # 把列表每一个元素传递到第一个函数中 函数返回True 把这个元素放到结果集中并返回
result = filter(func, list1)
print(list(result))
模拟filter函数
def my_filter(l,func):
# 结果
new_l = []
# 遍历列表每一个元素是否需要添加到new_l
for ele in l:
if func(ele):
new_l.append(ele)
return new_l
result = my_filter(list1,func)
print(result)
高阶函数作用:增加函数通用性(数据 操作)
文件I/O
文件I/O流程
文件
持久化存储
文件I/O
- 打开文件 open
- 文件I/O 读取:read 写入:write
- 文件关闭 close
文件的打开模式
功能 | r | r+ | w | w+ | a | a+ |
---|---|---|---|---|---|---|
读 | + | + | + | + | ||
写 | + | + | + | + | + | |
创建 | + | + | + | + | ||
覆盖 | + | + | ||||
指针在开始 | + | + | + | + | ||
指针在结尾 | + | + |
r模式
打开文件 默认r 只读模式
w模式
文件不存在 创建
文件存在 覆盖 但在文件打开后未关闭的状态下多次写入是不会覆盖的,而是追加
a模式
文件不存在 创建
**其他打开模式 **
r+、w+、a+
b不能单独存在 必须要和上面的模式组合 以二进制方式打开文件
默认没有b以文本方式打开文件
所有的文件都可以使用二进制打开
文本可以不用b模式打开
视频 图片 pdf word 使用b打开
rb
rb+
wb
wb+
ab
ab+
文件打开
f = open(文件路径,打开模式默认r)
文件关闭
f.close()
关闭文件,释放内存空间
文件写入
f.write(字符串类型数据)
文件读取
read
# 打开文件
f = open('b.txt','r')
# 读取 默认参数-1 代表读取所有文件内容
# 参数什么情况下需要: 1G
# content = f.read()
# 读取之后数据在内存,如果一次性全部读取数据过大,内存不够用,就需要分次读取
content = f.read(4096) #读取的长度,这里不是字节,可以理解成中文的一个两个元素
print(content)
# 关闭文件
f.close()
注意:如果文件比较大,需要指定读取内容个数
readlines
f = open('test.txt', 'r')
# 文件 1G
# 默认参数 -1 读取所有
con = f.readlines()
# con = f.readlines(15)
print(con)
f.close()
readline
f = open('test.txt', 'r')
con = f.readline()
print(con)
con = f.readline()
print(con)
con = f.readline()
print(con)
f.close()
tell
获取当前指针的位置
i = f.tell()
seek
移动指针的位置
文件对象.seek(偏移量,基准点)
第二个参数:
0: 文件开始点作为基准点
1:当前位置
2:尾部位置
注意:
如果打开模式不是b模式,seek必须要有一个参数为0
如果模式有b 可以不受这个限制
其它数据类型bool判断
# b = True
# b = 0
# b = 0.0
# 空位False 非空 True
# b = ' '
# b = [1]
# b = (1,)
# b = set()
# b = {'name':'张三'}
b = None
if b:
print('True')
else:
print('False')
绝对路径和相对路径
绝对路径
绝对路径指的是在电脑硬盘上真正保存的路径
# 第一个参数:文件路径
f = open('D:\\codespace\\AI\\01\\Day08\\test.txt')
content = f.read()
print(content)
f.close()
windows:有盘符概念
linux:都是在根路径/下面
绝对路径缺点:工程路径发生变化 文件路径需要重新指定
相对路径
相对路径就是相对于当前目录的路径
相对路径用.代表当前目录,使用…代表上一级目录
f = open('../../test.txt')
print(f.read())
f.close()
开发中尽量使用相对路径
编码和解码
- 所有存储的数据都是二进制存储 0101
乱码
编码和解码使用码表不相同
解决方案
f = open('l.txt','w',encoding='utf-8')
# cp936 chcp 936 GBK
print(f.encoding)
f.write('中国')
f.close()
设置编码方式为utf-8
文件和文件夹的其它操作
文件的重命名
import os
# 1. rename(): 重命名
os.rename('1.txt', '10.txt')
文件删除
os.remove('10.txt')
创建文件夹
os.mkdir(文件夹路径)
删除文件夹
os.rmdir(文件夹路径)
注意:只能删除空文件夹
可以先删除下面所有的文件,再删除这个文件夹
获取工作目录
os.getcwd()
切换工作目录
os.chdir('aa')
列举目录下所有的文件
os.listdir('./test')
如何修改每一层对应的文件前缀 如何获取里面所有的文件 ,递归