1.函数的初识
写一个获取字符串总个数的代码,不能用len:
s1 = 'fjkdsfjdssudafurpojurojregreuptotuproq[t'
# python没有len
count = 0
for i in s1:
count += 1
print(count)写一个获取列表总个数的代码:
这样的写代码low,
l1 = [1, 2, 3, 4, 5, 6]
count = 0
for i in l1:
count += 1
# print(count)
重复代码太多。
代码的可读性差。利用函数写出上面的功能:
s1 = 'fsjkdafshdjfsdhafjksda'
l1 = [1,2,3,4,5,6]def my_len(s): count = 0 for i in s: count += 1 print(count) my_len(s1) my_len(l1)
- 函数:以功能(完成一件事)为导向,登录,注册,len,一个函数就是一个功能。 随调随用。
- 函数的优点:
- 减少代码的重复性。
- 增强了代码的可读性。
1.函数的结构与调用
- 结构: def 关键字,定义函数。
meet 函数名:与变量设置相同,具有可描述性。
函数体 :缩进。函数中尽量不要出现 print - 函数什么时候执行?
- 当函数遇到 函数名() 函数才会执行!!!
def meet():
print('打开tantan')
print('左滑一下')
print('右滑一下')
print('找美女')
print('悄悄话....')
print('约....走起...')
meet()
meet()
meet()
- 当函数遇到 函数名() 函数才会执行!!!
2.函数的返回值
def meet():
print('打开tantan')
print('左滑一下')
return
print('右滑一下')
print('找美女')
print('悄悄话....')
print('约....走起...')
meet()
return: 在函数中遇到return直接结束函数。
def meet():
print('打开tantan')
print('左滑一下')
print('右滑一下')
print('找美女')
print('悄悄话....')
print('约....走起...')
return '妹子一枚'
ret = meet()
print(ret)
print(meet())
return 将数据返回给函数的执行者,调用者 meet()。
s1 = 'jfdkslfjsda'
ret = len(s1)
print(ret)
def meet():
print('打开tantan')
print('左滑一下')
print('右滑一下')
print('找美女')
print('悄悄话....')
print('约....走起...')
# return '妹子一枚'
return '妹子', 123, [22, 33]
ret= meet()
# ret,ret1,ret2 = meet()
print(ret,type(ret))
# return 返回多个元素 是以元组的形式返回给函数的执行者。
- 返回值的总结:
- 在函数中,终止函数。
- return 可以给函数的执行者返回值:
- return 单个值 单个值
- return 多个值 (多个值,)
3.函数的参数
def meet():
print('打开tantan')
print('进行筛选:性别:女')
print('左滑一下')
print('右滑一下')
print('找美女')
print('悄悄话....')
print('约....走起...')
s1 = 'jfdsklafjsda'
l1 = [1,2,3]
len(s1)
函数的传参:让函数封装的这个功能,盘活。
分两个角度:实参,形参。def meet(sex): #函数的定义:接受的参数形式参数
print('打开tantan')
print('进行筛选:性别:%s' %(sex))
print('左滑一下')
print('右滑一下')
print('找美女')
print('悄悄话....')
print('约....走起...')meet('男') # 函数的执行传的参数 :实际参数
实参角度
1.位置参数: 从左至右,一一对应。
- def meet(sex,age,skill):
print('打开tantan')
print('进行筛选:性别:%s,年龄:%s,%s' %(sex,age,skill))
print('左滑一下')
print('右滑一下')
print('找美女')
print('悄悄话....')
print('约....走起...')meet('女',25,'python技术好的',) 写一个函数,只接受两个int的参数,函数的功能是将较大的数返回。 def compile(a,b): c = 0 if a > b: return c else: return c print(compile(10,20)) print(compile(1000,1)) compile(1000,20) 三元与运算符: 简单的if else a = 1000 b = 2000 if a > b: c = a else: c = b print(c) a = 1000 b = 2000 c = a if a > b else b def complie(a,b): c = a if a > b else b return c def complie(a,b): return a if a > b else b
关键字参数
一一对应
def meet(sex,age,skill,hight,weight,):
print('打开tantan')
print('进行筛选:性别:%s,年龄:%s,技术:%s,身高:%s,体重%s' %(sex,age,skill,hight,weight))
print('左滑一下')
print('右滑一下')
print('找美女')
print('悄悄话....')
print('约....走起...')meet(age=25,weight=100,hight=174,skill='python技术好的',sex='女')
函数:传入两个字符串参数,将两个参数拼接完成后形成的结果返回。
一一对应
def meet(sex,age,skill,hight,weight,):
print('打开tantan')
print('进行筛选:性别:%s,年龄:%s,技术:%s,身高:%s,体重%s' %(sex,age,skill,hight,weight))
print('左滑一下')
print('右滑一下')
print('找美女')
print('悄悄话....')
print('约....走起...')meet(age=25,weight=100,hight=174,skill='python技术好的',sex='女')
函数:传入两个字符串参数,将两个参数拼接完成后形成的结果返回。
def func(a,b):
return a + b
print(func(b='太白',a='无敌'))混合参数
# 混合参数
# 位置参数一定要在关键字参数的前面。
def meet(sex,age,skill,hight,weight,):
print('打开tantan')
print('进行筛选:性别:%s,年龄:%s,技术:%s,身高:%s,体重%s' %(sex,age,skill,hight,weight))
print('左滑一下')
print('右滑一下')
print('找美女')
print('悄悄话....')
print('约....走起...')
return '筛选结果:性别:%s,体重%s' %(sex,weight)print(meet('女',25,weight=100,hight=174,skill='python技术好的'))
- 形参角度:
位置参数
def meet(sex,age,skill):
print('打开tantan')
print('进行筛选:性别:%s,年龄:%s,%s' %(sex,age,skill))
print('左滑一下')
print('右滑一下')
print('找美女')
print('悄悄话....')
print('约....走起...')meet('女',25,'python技术好的',) 写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。 def func(l): if len(l) > 2: return l[:2] else: return l # print(func([1,2,3,4,5])) print(func([1,])) def func(l): c = l[:2] if len(l) > 2 else l return c print(func([1,2,3,4,5])) print(func([1,])) def func(l): return l[:2] # l1 = [1,] # print(l1[:2])
默认参数
默认值参数
默认参数设置的意义:普遍经常使用的。def meet(age,skill='python技术好的',sex='女',): print('打开tantan') print('进行筛选:性别:%s,年龄:%s,技能:%s' %(sex,age,skill)) print('左滑一下') print('右滑一下') print('找美女') print('悄悄话....') print('约....走起...') # meet(25,'python技术好的',) meet(25,'运维技术好的','男') open()
函数:以功能(完成一件事)为导向,登录,注册,一个函数就是一个功能 随调随用
减少代码重复性
增强代码可读性
函数结构: def 关键字,定义函数
xxx 函数名:与变量设置相同,具有描述性
函数体; 缩进 函数中尽量不要出现print
def my_len(s):
count = 0
for i in s:
count += 1
print(count)
my_len(s1)
my_len(l1)
函数什么时候执行: 当函数遇到 函数名() 时函数才会执行
函数的返回值:
return:在函数中遇到return直接结束函数
将数据返回给函数的执行者,调用者
返回多个元素,是以元组的形式返回给函数的执行者
返回单个元素,是什么数据类型就返回什么数据类型
函数的传参:让函数封装这个功能,盘活
实参:函数的执行的参数
- 位置参数 :从左至右,一一对应
- 关键字参数:关键字一一对应,可以顺序不同
- 混合传参:位置参数一定要在关键字参数之前
形参: 函数定义,接受的参数形式参数
形参位置顺序:位置参数 *args 默认值参数 仅限关键字参数kwargs
- 位置参数
- 默认值参数
- 仅限关键字参数 位置在args和kwargs之间 如果需要传值必须要以关键字传值
- 万能参数:args 约定俗称(函数定义时:代表聚合) 他将所有的参数位置聚合成一个元组,赋值给了args
*kwargs 函数的定义时,**将所有的关键字参数聚合到一个字典中,将这个字典赋值给了kwargs
*在函数的调用时,代表打散 在字符串和列表中使用
**在函数的调用时,代表打散 在字典中使用
三元运算符:简单的if else c=a if a>b else b
# 三元与运算符: 简单的if else
# a = 1000
# b = 2000
# if a > b:
# c = a
# else:
# c = b
# print(c)
#
# a = 1000
# b = 2000
# c = a if a > b else b
# def complie(a,b):
# # c = a if a > b else b
# # return c
# return a if a > b else b
python分为三个空间:内置名称空间(builting。py)。全局名称空间(当前py文件)。局部名称空间 (函数执行时才开辟)
python中存在三个空间:
- 内置名称空间:存储的内置函数:print,input.......
- 全局名称空间:py文件,存放的是py文件(除去函数,类内部的)的变量,函数名与函数的内存地址的关系。
- 局部名称空间:存放的函数内部的变量与值的对应关系。
加载顺序:内置名称空间>全局名称空间>局部名称空间(函数执行时)
取值顺序:(j就近原则) 单向不可逆 legb原则
- (从局部找时)局部名称空间>全局名称空间>内置名称空间
作用域:
全局作用域:内置名称空间 全局名称空间
局部作用域:局部名称空间
局部作用域可以引用全局作用域的变量
局部作用域不能改变全局作用域的变量,当pyth解释器读取到局部作用域时,发现你对 变量进行修改的操作,解释器会认为你在局部已经定义过这个局部变量了,他就从局部找这个局部变量,就报错了
- 万能参数。
*的魔性用法。
# 万能参数。
# def eat(a,b,c,d):
# print('我请你吃:%s,%s,%s,%s' %(a,b,c,d))
#
# eat('蒸羊羔', '蒸熊掌', '蒸鹿邑','烧花鸭')# def eat(a,b,c,d,e,f): # print('我请你吃:%s,%s,%s,%s,%s,%s' %(a,b,c,d,e,f)) # # eat('蒸羊羔', '蒸熊掌', '蒸鹿邑','烧花鸭','烧雏鸡','烧子鹅') # 急需要一种形参,可以接受所有的实参。#万能参数。 # 万能参数: *args, 约定俗称:args, # 函数定义时,*代表聚合。 他将所有的位置参数聚合成一个元组,赋值给了 args。 # def eat(*args): # print(args) # print('我请你吃:%s,%s,%s,%s,%s,%s' % args) # # eat('蒸羊羔', '蒸熊掌', '蒸鹿邑','烧花鸭','烧雏鸡','烧子鹅') # 写一个函数:计算你传入函数的所有的数字的和。 # def func(*args): # count = 0 # for i in args: # count += i # return count # print(func(1,2,3,4,5,6,7)) # tu1 = (1, 2, 3, 4, 5, 6, 7) # count = 0 # for i in tu1: # count += i # print(count) # **kwargs # 函数的定义时: ** 将所有的关键字参数聚合到一个字典中,将这个字典赋值给了kwargs. # def func(**kwargs): # print(kwargs) # func(name='alex',age=73,sex='laddyboy') # 万能参数:*args, **kwargs, # def func(*args,**kwargs): # print(args) # print(kwargs) # func() # print() # * **在函数的调用时,*代表打散。 def func(*args,**kwargs): print(args) # (1,2,3,22,33) print(kwargs) # func(*[1,2,3],*[22,33]) # func(1,2,3,22,33) # func(*'fjskdfsa',*'fkjdsal') # func(1,2,3,22,33) func(**{'name': '太白'},**{'age': 18}) #func(name='太白',age='18')
- 仅限关键字参数(了解)。
形参的最终顺序。
# 形参角度的参数的顺序
# args 的位置?
# def func(args,a,b,sex= '男'):
# print(a,b)
# func(1,2,3,4)
# args得到实参的前提,sex必须被覆盖了。
# def func(a,b,sex= '男',*args,):
# print(a,b)
# print(sex)
# print(args)
# func(1,2,3,4,5,6,7,)# def func(a,b,*args,sex= '男'): # print(a,b) # print(sex) # print(args) # func(1,2,3,4,5,6,7,sex='女') # **kwargs 位置? def func(a,b,*args,sex= '男',**kwargs,): print(a,b) print(sex) print(args) print(kwargs) # func(1,2,3,4,5,6,7,sex='女',name='Alex',age=80) # 形参角度第四个参数:仅限关键字参数 (了解) def func(a,b,*args,sex= '男',c,**kwargs,): print(a,b) print(sex) print(args) print(c) print(kwargs) # func(1,2,3,4,5,6,7,sex='女',name='Alex',age=80,c='666') # 形参角度最终的顺序:位置参数,*args,默认参数,仅限关键字参数,**kwargs
4.默认参数和局部作用域的坑
1.默认参数的陷阱只针对于默认参数是可变的数据类型:
如果那你的默认参数指向的是可变的数据类型,那么你无论调用多少次这个默认参数,都是同一个
def func(a, list=[]):
# list.append(a)
# return list
# print(func(10,)) # [10,]
# print(func(20,[])) # [20,]
# print(func(100,)) # [10,100]
2.局部作用域的坑:
2.在函数中,如果你定义了一个变量,但是在定义这个变量之前对其引用了,那么解释器认为:语法问题
解决方便:你应该在使用之前先定义
3.global
在局部作用域声明一个全局变量
name = 'alex'def func(): global name name = '太白金星' # print(name) func() print(name)
- 修改一个全局变量
count = 1
def func():
# print(count)
global count
count += 1
print(count)
func()
print(count)
4.nonlocal- 不能操作一个全局变量
- 局部作用域:内层函数对外层函数的局部变量进行修改
def wrapper():
count = 1
def inner():
nonlocal count
count += 1
print(count)
inner()
print(count)
wrapper()
5.函数名
1.函数名指向的是函数的内存地址
2.函数名可以是一个变量
def func():
# print(666)
f = func
# f1 = f
# f2 = f1
# f()
# func()
# f1()
# f2()
3.函数名可以作为一个容器类数据类型元素
def func1():
# print('in func1')
#
# def func2():
# print('in func2')
#
# def func3():
# print('in func3')
l1 = [func1,func2,func3]
# for i in l1:
# i()
4.函数名可以作为函数的参数
# def func():
# print('in func')
#
# def func1(x):
# x() # func()
# print('in func1')
#
# func1(func)
5.函数名可以作为函数的返回值
def func():
print('in func')
def func1(x): # x = func
print('in func1')
return x
ret = func1(func) # func
ret() # func()
新特性:格式化输出 解释器3.6之后的
优点:1.结构更加简化2.可以结合表达式,函数进行使用3.效率提示很多
# %s format
# name = '太白'
# age = 18
# msg = '我叫%s,今年%s' %(name,age)
# msg1 = '我叫{},今年{}'.format(name,age)
# 新特性:格式化输出
# name = '太白'
# age = 18
# msg = f'我叫{name},今年{age}'
# print(msg)
# 可以加表达式
# dic = {'name':'alex','age': 73}
# msg = f'我叫{dic["name"]},今年{dic["age"]}'
# print(msg)
# count = 7
# print(f'最终结果:{count**2}')
# name = 'barry'
# msg = f'我的名字是{name.upper()}'
# print(msg)
# 结合函数写:
def _sum(a,b):
return a + b
msg = f'最终的结果是:{_sum(10,20)}'
print(msg)
# ! , : { } ;这些标点不能出现在{} 这里面
6.可迭代对象
- 字面意思:可以进行循环更新的一个实实在在值。
- 专业角度: 内部含有'iter'方法的对象,可迭代对象。
- 判断一个对象是不是可迭代对象: 'iter' in dir(对象)
- str list tuple dict set range
- 优点:
- 存储的数据直接能显示,比较直观。
- 拥有的方法比较多,操作方便。
- 缺点:
- 占用内存。
- 不能直接通过for循环,不能直接取值(索引,key)。
- 获取对象的所有方法并且以字符串的形式表现:dir()
- 判断一个对象是否是可迭代对象
s1 = 'fjdskl'
# l1 = [1,2,3]
# # print(dir(s1))
# print(dir((l1)))
# print('iter' in dir(s1))
# print('iter' in dir(range(10)))
7.迭代器
字面意思:更新迭代,器:工具:可更新迭代的工具。
专业角度:内部含有'iter'方法并且含有'next'方法的对象就是迭代器。
优点:
节省内存。
惰性机制,next一次,取一个值。
缺点:
速度慢。
不走回头路。
- 判断一个对象是否是迭代器
with open('文件1',encoding='utf-8',mode='w') as f1:
print(('iter' in dir(f1)) and ('next' in dir(f1))) 迭代器的取值
s1 = 'fjdag'
obj = iter(s1) # s1.__iter__()
# print(obj)
# print(next(obj)) # print(obj.__next__())
# print(next(obj)) # print(obj.__next__())
# print(next(obj)) # print(obj.__next__())
# print(next(obj)) # print(obj.__next__())
# print(next(obj)) # print(obj.__next__())
# print(next(obj)) # print(obj.__next__())# l1 = [11,22,33,44,55,66] # obj = iter(l1) # print(next(obj)) # print(next(obj)) # print(next(obj)) # print(next(obj)) # print(next(obj)) # print(next(obj))
可迭代对象如何转化成迭代器
iter([1,2,3])
8.while循环模拟for循环机制
l1 = [11,22,33,44,55,66,77,88,99,1111,1133,15652]
# 将可迭代对象转化成迭代器。
obj = iter(l1)
while 1:
try:
print(next(obj))
except StopIteration:
break
9.生成器
- 生成器:python社区,生成器与迭代器看成是一种。生成器的本质就是迭代器。唯一的区别:生成器是我们自己用python代码构建的数据结构。迭代器都是提供的,或者转化得来的。
- 获取生成器的三种方式:
- 生成器函数。
- 生成器表达式。
- python内部提供的一些
- 生成器函数获得生成器:
生成器函数获得生成器: 一个next对应一个yiled
函数
def func():
print(111)
print(222)
return 3
ret=func()
print(ret)生成器函数 def func(): print(111) print(222) yield 3 yield 55 ret=func() print(next(ret))
- yiled return
return:函数中只存在一个return就结束函数,并且给函数的执行者返回值
yiled:只要函数中有yiled那么他就是生成器函数,而不是函数了。生成器函数中可以存在多个yiled,yield不会结束生成器函数,一个yiled对应一个next
yiled from
def func():
l2=[1,2,3,4,5]
yield from l2
ret=func()
print(next(ret))
print(next(ret))
print(next(ret))
print(next(ret))
print(next(ret))
- yiled return
- 获取生成器的三种方式:
10.生成器表达式,列表推导式
- 用一行代码构建一个比较复杂有规律的列表
- 列表推导式
循环模式:[变量(加工后的变量) for 变量 in iterable]
l1=[i for i in range(1,11)]
print(l1)1-10的平方 l1=[i**2 for i in range(1,11)] print(l1) 构建一个列表: [2,3,4,5,6,7,8,9,10,'j','Q','K','A'] # l1 = [i for i in range(2,11)] + list('JQKA') # print(l1) 简单说法 l1 = [i for i in range(2,11)] + ['j','Q','K','A'] print(l1)
- 筛选模式:[变量(加工后的 变量) for 变量 in interable if
-
-
-
30以内三的倍数 l1=[i for i in range(1,31) if i%3==0] print(l1) 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母 # l1 = ['barry', 'ab', 'alex', 'wusir', 'xo'] # print([i.upper() for i in l1 if len(i) >= 3 ]) # 含有两个'e'的所有的人名全部大写留下来 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] l1 = [] for i in names: for name in i: if name.count('e') == 2: l1.append(name) print(l1) print([name.upper() for i in names for name in i if name.count('e') == 2])
-
-
-
11.匿名函数
- 匿名函数:一句话函数,比较简单的函数。
语法:函数名 = lambda 参数:返回值
- 此函数不是没有名字,他是有名字的,他的名字就是你给其设置的变量,比如func.
- lambda 是定义匿名函数的关键字,相当于函数的def.
- lambda 后面直接加形参,形参加多少都可以,只要用逗号隔开就行。
- 返回值在冒号之后设置,返回值和正常的函数一样,可以是任意数据类型。
- 匿名函数不管多复杂.只能写一行.且逻辑结束后直接返回数据
课上练习:
def func(a,b):
return a + b
# 构建匿名函数
func1 = lambda a,b: a + b
print(func1(1,2))
- 接收一个可切片的数据,返回索引为0与2的对应的元素(元组形式)。
func2 = lambda a: (a[0],a[2]) print(func2([22,33,44,55]))
- 写匿名函数:接收两个int参数,将较大的数据返回。
lambda a,b: a if a > b else b
12.内置函数
内置函数: *** 加key的。min,max,sorted,map,reduce,filter
# # python 提供了68个内置函数。
# # 今天讲的这部分大部分了解即可。
1.
# # eval 剥去字符串的外衣运算里面的代码,有返回值。 **
# s1 = '1 + 3'
# # print(s1)
# # print(eval(s1)) **
# # s = '{"name": "alex"}'
# # print(s,type(s))
# # print(dict(s)) # 不行
# # print(eval(s),type(eval(s)))
# # 网络传输的str input 输入的时候,sql注入等等绝对不能使用eval。
2.
# # exec 与eval几乎一样, 代码流。
# msg = """
# for i in range(10):
# print(i)
# """
# # print(msg)
# # exec(msg)
# # hash 哈希值
# # print(hash('fsjkdafsda'))
3.
# # help 帮助 **函数用于查看函数或模块用途的详细说明
# # s1 = 'fjdsls'
# # print(help(str))
# # print(help(str.upper))
# # s1 = 'sfsda'
# # s1.upper()
#
4.
# s1 = 'fdsklfa'
# # s1()
# def func():
# pass
# # func
# # # callable 判断一个对象是否可被调用 ***函数用于检查一个对象是否是可调用的。如果返回True,object仍然可能调用失败;但如果返回False,调用对象ojbect绝对不会成功。
# # print(callable(s1))
# # print(callable(func))
5.
# int 函数用于将一个字符串或数字转换为整型。
# print(int(3.6))
6.
# float 函数用于将整数和字符串转换成浮点数。
# print(type(3.6))
7.
complex:函数用于创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数。
# print(complex(1,2)) # (1+2j)
8.
# bin:将十进制转换成二进制并返回。 **
# print(bin(100))
# # oct:将十进制转化成八进制字符串并返回。 **
# print(oct(10))
# # hex:将十进制转化成十六进制字符串并返回。 **
# print(hex(10))
# print(hex(13))
9.
# divmod **计算除数与被除数的结果,返回一个包含商和余数的元组(a // b, a % b)
# print(divmod(10,3))
# round:保留浮点数的小数位数 **
# print(round(3.141592653, 2)) # 3.14
# pow:求x**y次幂。(三个参数为x**y的结果对z取余)
# print(pow(2,3)) **
# print(pow(2,3,3)) # 2**3 % 3
10
# bytes ***用于不同编码之间的转化。
s1 = '太白'
# b = s1.encode('utf-8')
# print(b)
# b = bytes(s1,encoding='utf-8')
# print(b)
11
# ord:输入字符找该字符编码的位置
# ascii Unicode
# print(ord('a')) #
# print(ord('中')) # 20013 Unicode
# # chr:输入位置数字找出其对应的字符 # **
# # print(chr(97))
# print(chr(20013)) # Unicode
12
# repr:返回一个对象的string形式(原形毕露)。 ***
# s1 = '存龙'
# # # print(s1)
# # print(repr(s1))
# # msg = '我叫%s' %(s1)
# msg = '我叫%r' %(s1)
# print(msg)
# all:可迭代对象中,全都是True才是True
# l1 = [1, 2, '太白', True, [1,2,3], '']
# print(all(l1))
# any:可迭代对象中,有一个True 就是True
# l1 = [ 0, '太白', False, [], '',()]
# print(any(l1))
13
file: 默认是输出到屏幕,如果设置为文件句柄,输出到文件
sep: 打印多个值之间的分隔符,默认为空格
end: 每一次打印的结尾,默认为换行符
flush: 立即把内容输出到流文件,不作缓存
# print(self, *args, sep=' ', end='\n', file=None)
# print(1,2,3,4)
# print(1,2,3,4,sep='&')
# print(1, end=' ')
# print(2)
14
# list 将一个可迭代对象转换成列表
# l1 = [1,2,3,4]
# l2 = list()
# l2 = list('fjfdsklagjsflag')
# print(l2)
15
# dict 创建字典的几种方式
# 直接创建
# 元组的解构
# dic = dict([(1,'one'),(2,'two'),(3,'three')])
# dic = dict(one=1,two=2)
# print(dic)
# fromkeys
# update
# 字典的推导式
16
# abs() ***返回绝对值
# print(abs(-6))
17
# sum ***求和
# l1 = [i for i in range(10)]
# s1 = '12345'
# print(sum(l1))
# print(sum(l1,100))
# print(sum(s1)) # 错误
18
# reversed 将一个序列翻转, 返回翻转序列的迭代器 ***
# l1 = [i for i in range(10)]
# # l1.reverse() # 列表的方法
# # print(l1)
# l1 = [i for i in range(10)]
# obj = reversed(l1)
# print(l1)
# print(list(obj))
19
# zip 拉链方法 ***函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组然后返回由这些元祖组成的内容,如果各个迭代器的元素个数不一致,则按照长度最短的返回,
# l1 = [1, 2, 3, 4, 5]
# tu1 = ('太白', 'b哥', '德刚')
# s1 = 'abcd'
# obj = zip(l1,tu1,s1)
# # # print(obj)
# # for i in obj:
# # print(i)
# print(list(obj))
20
# ************* 以下方法最最最重要
# min max
l1 = [33, 2, 3, 54, 7, -1, -9]
# print(min(l1))
# 以绝对值的方式去最小值
# l2 = []
# func = lambda a: abs(a)
# for i in l1:
# l2.append(func(i))
# print(min(l2))
# def abss(a):
# '''
# 第一次:a = 33 以绝对值取最小值 33
# 第二次:a = 2 以绝对值取最小值 2
# 第三次:a = 3 以绝对值取最小值 2
# ......
# 第六次:a = -1 以绝对值取最小值 1
#
# '''
# return abs(a)
# print(min(l1,key=abss))
# 凡是可以加key的:它会自动的将可迭代对象中的每个元素按照顺序传入key对应的函数中,
# 以返回值比较大小。
dic = {'a': 3, 'b': 2, 'c': 1}
# 求出值最小的键
# print(min(dic)) # min默认会按照字典的键去比较大小。
# def func(a):
# return dic[a]
# func = lambda a:dic[a]
print(min(dic,key=lambda a: dic[a]))
21
sorted排序函数 语法:sorted(iterable,key=None,reverse=False)
iterable : 可迭代对象
key: 排序规则(排序函数),在sorted内部会将可迭代对象中的每一个元素传递给这个函数的参数.根据函数运算的结果进行排序
reverse :是否是倒叙,True 倒叙 False 正序
lst = [1,3,2,5,4]
lst2 = sorted(lst)
print(lst) #原列表不会改变
print(lst2) #返回的新列表是经过排序的
lst3 = sorted(lst,reverse=True)
print(lst3) #倒叙
结果:
[1, 3, 2, 5, 4]
[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]
字典使用sorted排序
dic = {1:'a',3:'c',2:'b'}
print(sorted(dic)) # 字典排序返回的就是排序后的key
结果:
[1,2,3]
22
# reduce 的使用方式:
# reduce(函数名,可迭代对象) # 这两个参数必须都要有,缺一个不行
from functools import reduce
def func(x,y):
return x + y
ret = reduce(func,[3,4,5,6,7])
print(ret) # 结果 25
reduce的作用是先把列表中的前俩个元素取出计算出一个值然后临时保存着,
接下来用这个临时保存的值和列表中第三个元素进行计算,求出一个新的值将最开始临时保存的值覆盖掉,然后在用这个新的临时值和列表中第四个元素计算.依次类推
23
映射函数
语法: map(function,iterable) 可以对可迭代对象中的每一个元素进映射,分别取执行function
计算列表中每个元素的平方,返回新列表
lst = [1,2,3,4,5]
def func(s):
return s*s
mp = map(func,lst)
print(mp)
print(list(mp))
改写成lambda
lst = [1,2,3,4,5]
print(list(map(lambda s:s*s,lst)))
计算两个列表中相同位置的数据的和
lst1 = [1, 2, 3, 4, 5]
lst2 = [2, 4, 6, 8, 10]
print(list(map(lambda x, y: x+y, lst1, lst2)))
结果:
[3, 6, 9, 12, 15]
24
filter 语法: filter(function,iterable)
function: 用来筛选的函数,在filter中会自动的把iterable中的元素传递给function,然后根据function返回的True或者False来判断是否保留此项数据
iterable:可迭代对象
lst = [{'id':1,'name':'alex','age':18},
{'id':1,'name':'wusir','age':17},
{'id':1,'name':'taibai','age':16},]
ls = filter(lambda e:e['age'] > 16,lst)
print(list(ls))
结果:
[{'id': 1, 'name': 'alex', 'age': 18},
{'id': 1, 'name': 'wusir', 'age': 17}]
13闭包
闭包: 多用于面试题: 什么是闭包? 闭包有什么作用。
# 1,闭包只能存在嵌套函数中。
# 2, 内层函数对外层函数非全局变量的引用(使用),就会形成闭包。
# 被引用的非全局变量也称作自由变量,这个自由变量会与内层函数产生一个绑定关系,
# 自由变量不会再内存中消失。
# 闭包的作用:保证数据的安全。
# 如何判断一个嵌套函数是不是闭包#
1,闭包只能存在嵌套函数中。
# 2, 内层函数对外层函数非全局变量的引用(使用),就会形成闭包
封闭的东西: 保证数据的安全。
# 方案一:
# l1 = [] # 全局变量 数据不安全
# li = []
# def make_averager(new_value):
# l1.append(new_value)
# total = sum(l1)
# averager = total/len(l1)
# return averager
# print(make_averager(100000))
# print(make_averager(110000))
# # 很多代码.....
# l1.append(666)
# print(make_averager(120000))
# print(make_averager(90000))
# 方案二: 数据安全,l1不能是全局变量。
# 每次执行的时候,l1列表都会重新赋值成[]
# li = []
# def make_averager(new_value):
# l1 = []
# l1.append(new_value)
# total = sum(l1)
# averager = total/len(l1)
# return averager
# print(make_averager(100000))
# print(make_averager(110000))
# # 很多代码.....
# print(make_averager(120000))
# print(make_averager(90000))
# 方案三: 闭包
#
def make_averager():
l1 = []
def averager(new_value):
l1.append(new_value)
print(l1)
total = sum(l1)
return total/len(l1)
return averager
# avg = make_averager() # averager
# print(avg(100000))
# print(avg(110000))
# print(avg(120000))
# print(avg(190000))
# def func():
# return 666
#
# ret = func()
# print(globals())
# 闭包: 多用于面试题: 什么是闭包? 闭包有什么作用。
# 1,闭包只能存在嵌套函数中。
# 2, 内层函数对外层函数非全局变量的引用(使用),就会形成闭包。
# 被引用的非全局变量也称作自由变量,这个自由变量会与内层函数产生一个绑定关系,
# 自由变量不会再内存中消失。
# 闭包的作用:保证数据的安全。
# 如何判断一个嵌套函数是不是闭包
# 1,闭包只能存在嵌套函数中。
# 2, 内层函数对外层函数非全局变量的引用(使用),就会形成闭包。
# 例一:
# def wrapper():
# a = 1
# def inner():
# print(a)
# return inner
# ret = wrapper()
#
# # 例二:
# a = 2
# def wrapper():
# def inner():
# print(a)
# return inner
# ret = wrapper()
# # 例三:
# 也是闭包!
# def wrapper(a,b):
# def inner():
# print(a)
# print(b)
# return inner
# a = 2
# b = 3
# ret = wrapper(a,b)
# print(ret.__code__.co_freevars) # ('a', 'b')
# 如何代码判断闭包?
def make_averager():
l1 = []
def averager(new_value):
l1.append(new_value)
print(l1)
total = sum(l1)
return total/len(l1)
return averager
avg = make_averager() # averager
print(avg.__code__.co_freevars)
14.装饰器
开放封闭原则:
装饰器:装饰,装修,房子就可以住,如果装修,不影响你住,而且体验更加,让你生活中增加了很多功能:洗澡,看电视,沙发。
器:工具。
开放封闭原则:
开放:对代码的拓展开放的, 更新地图,加新枪,等等。
封闭:对源码的修改是封闭的。闪躲用q。就是一个功能,一个函数。 别人赤手空拳打你,用机枪扫你,扔雷.....这个功能不会改变。装饰器:完全遵循开放封闭原则。 装饰器: 在不改变原函数的代码以及调用方式的前提下,为其增加新的功能。 装饰器就是一个函数。
- 装饰器的初识:
版本一: 大壮 写一些代码测试一下index函数的执行效率。
import time
# def index():
# '''有很多代码.....'''
# time.sleep(2) # 模拟的网络延迟或者代码效率
# print('欢迎登录博客园首页')
#
# def dariy():
# '''有很多代码.....'''
# time.sleep(3) # 模拟的网络延迟或者代码效率
# print('欢迎登录日记页面')# print(time.time()) # 格林威治时间。
# print(111)
# time.sleep(3)
# print(222)
# 版本一有问题: 如果测试别人的代码,必须重新赋值粘贴。
# start_time = time.time()
# index()
# end_time = time.time()
# print(end_time-start_time)
#
# start_time = time.time()
# dariy()
# end_time = time.time()
# print(end_time-start_time)
#
#
# start_time = time.time()
# # dariy()
# end_time = time.time()
# print(end_time-start_time)版本二:利用函数,解决代码重复使用的问题
import time
def index():
'''有很多代码.....'''
time.sleep(2) # 模拟的网络延迟或者代码效率
print('欢迎登录博客园首页')
# index()
def dariy():
'''有很多代码.....'''
time.sleep(3) # 模拟的网络延迟或者代码效率
print('欢迎登录日记页面')def timmer(f): # f= index start_time = time.time() f() # index() end_time = time.time() print(f'测试本函数的执行效率{end_time-start_time}') timmer(index) 版本二还是有问题: 原来index函数源码没有变化,给原函数添加了一个新的功能测试原函数的执行效率的功能。 满足开放封闭原则么?原函数的调用方式改变了。
版本三:不能改变原函数的调用方式。
# import time
# def index():
# '''有很多代码.....'''
# time.sleep(2) # 模拟的网络延迟或者代码效率
# print('欢迎登录博客园首页')
#
# def timmer(f): # f = index (funciton index123)
# def inner(): # inner :(funciton inner123)
# start_time = time.time()
# f() # index() (funciton index123)
# end_time = time.time()
# print(f'测试本函数的执行效率{end_time-start_time}')
# return inner # (funciton inner123)
# timmer(index) # index()
# ret = timmer(index) # inner
# ret() # inner()
# index = timmer(index) # inner (funciton inner123)
# index() # inner()
# def func():
# print('in func')
#
# def func1():
# print('in func1')
#
# # func()
# # func1()
# func()
# func = 666
# func(0)版本四:具体研究
import time
def index():
'''有很多代码.....'''
time.sleep(2) # 模拟的网络延迟或者代码效率
print('欢迎登录博客园首页')def timmer(f): f = index # f = <function index at 0x0000023BA3E8A268> def inner(): start_time = time.time() f() end_time = time.time() print(f'测试本函数的执行效率{end_time-start_time}') return inner index = timmer(index) index()
版本五:python做了一个优化;提出了一个语法糖的概念。 标准版的装饰器
import time
# timmer装饰器
def timmer(f):
def inner():
start_time = time.time()
f()
end_time = time.time()
print(f'测试本函数的执行效率{end_time-start_time}')
return inner# @timmer # index = timmer(index) def index(): '''有很多代码.....''' time.sleep(0.6) # 模拟的网络延迟或者代码效率 print('欢迎登录博客园首页') return 666 ret = index() print(ret) def dariy(): '''有很多代码.....''' time.sleep(3) # 模拟的网络延迟或者代码效率 print('欢迎登录日记页面') dariy() # index = timmer(index) # index() # dariy = timmer(dariy) @timmer dariy()
版本六:被装饰函数带返回值
import time
# timmer装饰器
def timmer(f):
# f = index
def inner():
start_time = time.time()
# print(f'这是个f():{f()}!!!') # index()
r = f()
end_time = time.time()
print(f'测试本函数的执行效率{end_time-start_time}')
return r
return inner@timmer # index = timmer(index) def index(): '''有很多代码.....''' time.sleep(0.6) # 模拟的网络延迟或者代码效率 print('欢迎登录博客园首页') return 666 # 加上装饰器不应该改变原函数的返回值,所以666 应该返回给我下面的ret, # 但是下面的这个ret实际接收的是inner函数的返回值,而666返回给的是装饰器里面的 # f() 也就是 r,我们现在要解决的问题就是将r给inner的返回值。 ret = index() # inner() print(ret)
版本七:被装饰函数带参数
import time
# timmer装饰器
def timmer(f):
# f = index
def inner(*args,**kwargs):
# 函数的定义:* 聚合 args = ('李舒淇',18)
start_time = time.time()
# print(f'这是个f():{f()}!!!') # index()
r = f(*args,**kwargs)
# 函数的执行:* 打散:f(args) --> f(('李舒淇',18)) --> f('李舒淇',18)
end_time = time.time()
print(f'测试本函数的执行效率{end_time-start_time}')
return r
return inner@timmer # index = timmer(index) def index(name): '''有很多代码.....''' time.sleep(0.6) # 模拟的网络延迟或者代码效率 print(f'欢迎{name}登录博客园首页') return 666 index('纳钦') # inner('纳钦') @timmer def dariy(name,age): '''有很多代码.....''' time.sleep(0.5) # 模拟的网络延迟或者代码效率 print(f'欢迎{age}岁{name}登录日记页面') dariy('李舒淇',18) # inner('李舒淇',18) 标准版的装饰器; def wrapper(f): def inner(*args,**kwargs): '''添加额外的功能:执行被装饰函数之前的操作''' ret = f(*args,**kwargs) ''''添加额外的功能:执行被装饰函数之后的操作''' return ret return inner
15.递归函数
递归函数;就是在一个函数里再调用这个函数本身,这种魔性的使用函数的方式就叫做递归。
# count = 0
# def func():
# global count
# count += 1
# print(count)
# func()
# print(456)
# func()
# RecursionError
# 递归的最大深度1000层 : 为了节省内存空间,不要让用户无限使用内存空间
# 1.递归要尽量控制次数,如果需要很多层递归才能解决问题,不适合用递归解决
# 2.循环和递归的关系
# 递归不是万能的
# 递归比起循环来说更占用内存
# 修改递归的最大深度
# import sys
# sys.setrecursionlimit(1000000000)
递归函数如何停止
# count = 0
# def func(): # func1
# global count
# count += 1 # 1
# print(count)
# if count == 3: return
# func()
# print(456)
# func()
#
# def func(): # func2
# global count
# count += 1 # 2
# print(count)
# if count == 3: return
# func()
# print(456)
#
#
# def func(): # func3
# global count
# count += 1 # 3
# print(count)
# if count == 3:return
# func()
# print(456)
一个递归函数要想结束,必须在函数内写一个return,并且return的条件必须是一个可达到的条件
# 并不是函数中有return,return的结果就一定能够在调用函数的外层接收到
# def func(count):
# count += 1
# print(count)
# if count == 5 : return 5
# ret = func(count)
# print(count ,':',ret)
# return ret
# print('-->',func(1))
# def func(1):
# 1 += 1
# print(2)
# if 2 == 5 : return 5
# ret = func(2)
# print(ret)
# return ret
#
# def func(2):
# 2 += 1
# print(3)
# if 3 == 5 : return 5
# ret = func(3)
# print(ret)
# return ret
#
# def func(3):
# 3 += 1
# print(4)
# if 4 == 5 : return 5
# ret = func(4)
# print(ret)
# return ret
#
# def func(4):
# 4 += 1
# print(5)
# if 5 == 5 : return 5
# func(count)
#
# def func(count):
# count += 1
# print(count)
# if count == 5 : return 5
# return func(count)
# print('-->',func(1))